server: proxy: refactor
This commit is contained in:
parent
f5d32f4617
commit
8a75e8f54e
@ -35,7 +35,6 @@ static BOOL demo_filter_mouse_event(moduleOperations* module, rdpContext* contex
|
|||||||
|
|
||||||
if (event_data->x % 100 == 0)
|
if (event_data->x % 100 == 0)
|
||||||
{
|
{
|
||||||
module->AbortConnect(module, context);
|
|
||||||
printf("filter_demo: mouse x is currently %"PRIu16"\n", event_data->x);
|
printf("filter_demo: mouse x is currently %"PRIu16"\n", event_data->x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,16 +53,13 @@
|
|||||||
|
|
||||||
#define TAG PROXY_TAG("client")
|
#define TAG PROXY_TAG("client")
|
||||||
|
|
||||||
/**
|
|
||||||
* Re-negotiate with original client after negotiation between the proxy
|
|
||||||
* and the target has finished.
|
|
||||||
*/
|
|
||||||
static BOOL proxy_server_reactivate(rdpContext* ps, const rdpContext* pc)
|
static BOOL proxy_server_reactivate(rdpContext* ps, const rdpContext* pc)
|
||||||
{
|
{
|
||||||
if (!pf_context_copy_settings(ps->settings, pc->settings))
|
if (!pf_context_copy_settings(ps->settings, pc->settings))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* DesktopResize causes internal function rdp_server_reactivate to be called,
|
/*
|
||||||
|
* DesktopResize causes internal function rdp_server_reactivate to be called,
|
||||||
* which causes the reactivation.
|
* which causes the reactivation.
|
||||||
*/
|
*/
|
||||||
if (!ps->update->DesktopResize(ps))
|
if (!ps->update->DesktopResize(ps))
|
||||||
@ -74,17 +71,17 @@ static BOOL proxy_server_reactivate(rdpContext* ps, const rdpContext* pc)
|
|||||||
static void pf_OnErrorInfo(void* ctx, ErrorInfoEventArgs* e)
|
static void pf_OnErrorInfo(void* ctx, ErrorInfoEventArgs* e)
|
||||||
{
|
{
|
||||||
pClientContext* pc = (pClientContext*) ctx;
|
pClientContext* pc = (pClientContext*) ctx;
|
||||||
proxyData* pdata = pc->pdata;
|
pServerContext* ps = pc->pdata->ps;
|
||||||
rdpContext* ps = (rdpContext*)pdata->ps;
|
|
||||||
|
|
||||||
if (e->code != ERRINFO_NONE)
|
if (e->code == ERRINFO_NONE)
|
||||||
{
|
return;
|
||||||
const char* errorMessage = freerdp_get_error_info_string(e->code);
|
|
||||||
WLog_WARN(TAG, "Proxy's client received error info pdu from server: (0x%08"PRIu32"): %s", e->code, errorMessage);
|
WLog_WARN(TAG, "received error info code: 0x%08"PRIu32", msg: %s", e->code,
|
||||||
/* forward error back to client */
|
freerdp_get_error_info_string(e->code));
|
||||||
freerdp_set_error_info(ps->rdp, e->code);
|
|
||||||
freerdp_send_error_info(ps->rdp);
|
/* forward error back to client */
|
||||||
}
|
freerdp_set_error_info(ps->context.rdp, e->code);
|
||||||
|
freerdp_send_error_info(ps->context.rdp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL pf_client_load_rdpsnd(pClientContext* pc, proxyConfig* config)
|
static BOOL pf_client_load_rdpsnd(pClientContext* pc, proxyConfig* config)
|
||||||
@ -130,22 +127,28 @@ static BOOL pf_client_pre_connect(freerdp* instance)
|
|||||||
* as the client's settings are copied from the server's, GlyphSupportLevel might not be
|
* as the client's settings are copied from the server's, GlyphSupportLevel might not be
|
||||||
* GLYPH_SUPPORT_NONE. the proxy currently do not support GDI & GLYPH_SUPPORT_CACHE, so
|
* GLYPH_SUPPORT_NONE. the proxy currently do not support GDI & GLYPH_SUPPORT_CACHE, so
|
||||||
* GlyphCacheSupport must be explicitly set to GLYPH_SUPPORT_NONE.
|
* GlyphCacheSupport must be explicitly set to GLYPH_SUPPORT_NONE.
|
||||||
|
*
|
||||||
|
* Also, OrderSupport need to be zeroed, because it is currently not supported.
|
||||||
*/
|
*/
|
||||||
settings->GlyphSupportLevel = GLYPH_SUPPORT_NONE;
|
settings->GlyphSupportLevel = GLYPH_SUPPORT_NONE;
|
||||||
|
ZeroMemory(instance->settings->OrderSupport, 32);
|
||||||
|
|
||||||
settings->OsMajorType = OSMAJORTYPE_UNIX;
|
settings->OsMajorType = OSMAJORTYPE_UNIX;
|
||||||
settings->OsMinorType = OSMINORTYPE_NATIVE_XSERVER;
|
settings->OsMinorType = OSMINORTYPE_NATIVE_XSERVER;
|
||||||
|
|
||||||
/**
|
settings->SupportDynamicChannels = TRUE;
|
||||||
* settings->OrderSupport is initialized at this point.
|
|
||||||
* Only override it if you plan to implement custom order
|
|
||||||
* callbacks or deactiveate certain features.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* currently not supporting GDI orders */
|
/* Multimon */
|
||||||
ZeroMemory(instance->settings->OrderSupport, 32);
|
settings->UseMultimon = TRUE;
|
||||||
|
|
||||||
|
/* Sound */
|
||||||
|
settings->AudioPlayback = FALSE;
|
||||||
|
settings->DeviceRedirection = TRUE;
|
||||||
|
|
||||||
|
/* Display control */
|
||||||
|
settings->SupportDisplayControl = config->DisplayControl;
|
||||||
|
settings->DynamicResolutionUpdate = config->DisplayControl;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register the channel listeners.
|
* Register the channel listeners.
|
||||||
* They are required to set up / tear down channels if they are loaded.
|
* They are required to set up / tear down channels if they are loaded.
|
||||||
@ -224,6 +227,12 @@ static BOOL pf_client_post_connect(freerdp* instance)
|
|||||||
}
|
}
|
||||||
|
|
||||||
pf_client_register_update_callbacks(update);
|
pf_client_register_update_callbacks(update);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* after the connection fully established and settings were negotiated with target server, send
|
||||||
|
* a reactivation sequence to the client with the negotiated settings. This way, settings are
|
||||||
|
* synchorinized between proxy's peer and and remote target.
|
||||||
|
*/
|
||||||
return proxy_server_reactivate(ps, context);
|
return proxy_server_reactivate(ps, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,6 +266,44 @@ static void pf_client_post_disconnect(freerdp* instance)
|
|||||||
proxy_data_abort_connect(pdata);
|
proxy_data_abort_connect(pdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL pf_client_connect(freerdp* instance)
|
||||||
|
{
|
||||||
|
pClientContext* pc = (pClientContext*) instance->context;
|
||||||
|
rdpSettings* settings = pc->context.settings;
|
||||||
|
|
||||||
|
/* on first try, proxy client should always try to connect with NLA */
|
||||||
|
settings->NlaSecurity = TRUE;
|
||||||
|
pc->during_connect_process = TRUE;
|
||||||
|
|
||||||
|
if (!freerdp_connect(instance))
|
||||||
|
{
|
||||||
|
if (settings->NlaSecurity)
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "freerdp_connect() failed, trying to connect without NLA");
|
||||||
|
|
||||||
|
/* disable NLA, enable TLS */
|
||||||
|
settings->NlaSecurity = FALSE;
|
||||||
|
settings->RdpSecurity = TRUE;
|
||||||
|
settings->TlsSecurity = TRUE;
|
||||||
|
|
||||||
|
pc->during_connect_process = FALSE;
|
||||||
|
if (!freerdp_connect(instance))
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "connection failure");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "connection failure");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pc->during_connect_process = FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RDP main loop.
|
* RDP main loop.
|
||||||
* Connects RDP, loops while running and handles event and dispatch, cleans up
|
* Connects RDP, loops while running and handles event and dispatch, cleans up
|
||||||
@ -272,9 +319,6 @@ static DWORD WINAPI pf_client_thread_proc(LPVOID arg)
|
|||||||
DWORD status;
|
DWORD status;
|
||||||
HANDLE handles[65];
|
HANDLE handles[65];
|
||||||
|
|
||||||
if (!pf_modules_run_hook(HOOK_TYPE_CLIENT_PRE_CONNECT, (rdpContext*) ps))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* during redirection, freerdp's abort event might be overriden (reset) by the library, after
|
* during redirection, freerdp's abort event might be overriden (reset) by the library, after
|
||||||
* the server set it in order to shutdown the connection. it means that the server might signal
|
* the server set it in order to shutdown the connection. it means that the server might signal
|
||||||
@ -284,42 +328,11 @@ static DWORD WINAPI pf_client_thread_proc(LPVOID arg)
|
|||||||
*/
|
*/
|
||||||
handles[64] = pdata->abort_event;
|
handles[64] = pdata->abort_event;
|
||||||
|
|
||||||
/* on first try, proxy client should always try to connect with NLA */
|
if (!pf_modules_run_hook(HOOK_TYPE_CLIENT_PRE_CONNECT, (rdpContext*) ps))
|
||||||
instance->settings->NlaSecurity = TRUE;
|
return FALSE;
|
||||||
|
|
||||||
/*
|
if (!pf_client_connect(instance))
|
||||||
* Only set the `during_connect_process` flag if NlaSecurity is enabled.
|
return FALSE;
|
||||||
* If NLASecurity isn't enabled, the connection should be closed right after the first failure.
|
|
||||||
*/
|
|
||||||
if (instance->settings->NlaSecurity)
|
|
||||||
pc->during_connect_process = TRUE;
|
|
||||||
|
|
||||||
if (!freerdp_connect(instance))
|
|
||||||
{
|
|
||||||
if (instance->settings->NlaSecurity)
|
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "freerdp_connect() failed, trying to connect without NLA");
|
|
||||||
|
|
||||||
/* disable NLA, enable TLS */
|
|
||||||
instance->settings->NlaSecurity = FALSE;
|
|
||||||
instance->settings->RdpSecurity = TRUE;
|
|
||||||
instance->settings->TlsSecurity = TRUE;
|
|
||||||
|
|
||||||
pc->during_connect_process = FALSE;
|
|
||||||
if (!freerdp_connect(instance))
|
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "connection failure");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "connection failure");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pc->during_connect_process = FALSE;
|
|
||||||
|
|
||||||
while (!freerdp_shall_disconnect(instance))
|
while (!freerdp_shall_disconnect(instance))
|
||||||
{
|
{
|
||||||
|
@ -26,6 +26,9 @@
|
|||||||
static BOOL client_to_proxy_context_new(freerdp_peer* client,
|
static BOOL client_to_proxy_context_new(freerdp_peer* client,
|
||||||
pServerContext* context)
|
pServerContext* context)
|
||||||
{
|
{
|
||||||
|
context->dynvcReady = NULL;
|
||||||
|
context->modules_info = NULL;
|
||||||
|
|
||||||
context->modules_info = HashTable_New(TRUE);
|
context->modules_info = HashTable_New(TRUE);
|
||||||
if (!context->modules_info)
|
if (!context->modules_info)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -33,12 +36,24 @@ static BOOL client_to_proxy_context_new(freerdp_peer* client,
|
|||||||
context->vcm = WTSOpenServerA((LPSTR) client->context);
|
context->vcm = WTSOpenServerA((LPSTR) client->context);
|
||||||
|
|
||||||
if (!context->vcm || context->vcm == INVALID_HANDLE_VALUE)
|
if (!context->vcm || context->vcm == INVALID_HANDLE_VALUE)
|
||||||
goto fail_open_server;
|
goto error;
|
||||||
|
|
||||||
|
if (!(context->dynvcReady = CreateEvent(NULL, TRUE, FALSE, NULL)))
|
||||||
|
goto error;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
fail_open_server:
|
|
||||||
|
error:
|
||||||
HashTable_Free(context->modules_info);
|
HashTable_Free(context->modules_info);
|
||||||
|
WTSCloseServer((HANDLE)context->vcm);
|
||||||
context->vcm = NULL;
|
context->vcm = NULL;
|
||||||
|
|
||||||
|
if (context->dynvcReady)
|
||||||
|
{
|
||||||
|
CloseHandle(context->dynvcReady);
|
||||||
|
context->dynvcReady = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,11 +77,12 @@ static void client_to_proxy_context_free(freerdp_peer* client,
|
|||||||
HashTable_Free(context->modules_info);
|
HashTable_Free(context->modules_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL init_p_server_context(freerdp_peer* client)
|
BOOL pf_context_init_server_context(freerdp_peer* client)
|
||||||
{
|
{
|
||||||
client->ContextSize = sizeof(pServerContext);
|
client->ContextSize = sizeof(pServerContext);
|
||||||
client->ContextNew = (psPeerContextNew) client_to_proxy_context_new;
|
client->ContextNew = (psPeerContextNew) client_to_proxy_context_new;
|
||||||
client->ContextFree = (psPeerContextFree) client_to_proxy_context_free;
|
client->ContextFree = (psPeerContextFree) client_to_proxy_context_free;
|
||||||
|
|
||||||
return freerdp_peer_context_new(client);
|
return freerdp_peer_context_new(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,7 +138,7 @@ BOOL pf_context_copy_settings(rdpSettings* dst, const rdpSettings* src)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
rdpContext* p_client_context_create(rdpSettings* clientSettings)
|
rdpContext* pf_context_create_client_context(rdpSettings* clientSettings)
|
||||||
{
|
{
|
||||||
RDP_CLIENT_ENTRY_POINTS clientEntryPoints;
|
RDP_CLIENT_ENTRY_POINTS clientEntryPoints;
|
||||||
rdpContext* context;
|
rdpContext* context;
|
||||||
|
@ -34,7 +34,6 @@
|
|||||||
|
|
||||||
#include "pf_config.h"
|
#include "pf_config.h"
|
||||||
#include "pf_server.h"
|
#include "pf_server.h"
|
||||||
#include "pf_modules.h"
|
|
||||||
|
|
||||||
typedef struct proxy_data proxyData;
|
typedef struct proxy_data proxyData;
|
||||||
|
|
||||||
@ -43,7 +42,7 @@ typedef struct proxy_data proxyData;
|
|||||||
*/
|
*/
|
||||||
struct p_server_context
|
struct p_server_context
|
||||||
{
|
{
|
||||||
rdpContext _context;
|
rdpContext context;
|
||||||
|
|
||||||
proxyData* pdata;
|
proxyData* pdata;
|
||||||
|
|
||||||
@ -65,7 +64,7 @@ typedef struct p_server_context pServerContext;
|
|||||||
*/
|
*/
|
||||||
struct p_client_context
|
struct p_client_context
|
||||||
{
|
{
|
||||||
rdpContext _context;
|
rdpContext context;
|
||||||
|
|
||||||
proxyData* pdata;
|
proxyData* pdata;
|
||||||
|
|
||||||
@ -100,18 +99,14 @@ struct proxy_data
|
|||||||
HANDLE client_thread;
|
HANDLE client_thread;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* client */
|
BOOL pf_context_copy_settings(rdpSettings* dst, const rdpSettings* src);
|
||||||
rdpContext* p_client_context_create(rdpSettings* clientSettings);
|
BOOL pf_context_init_server_context(freerdp_peer* client);
|
||||||
|
rdpContext* pf_context_create_client_context(rdpSettings* clientSettings);
|
||||||
|
|
||||||
/* pdata */
|
|
||||||
proxyData* proxy_data_new(void);
|
proxyData* proxy_data_new(void);
|
||||||
void proxy_data_free(proxyData* pdata);
|
void proxy_data_free(proxyData* pdata);
|
||||||
|
|
||||||
BOOL pf_context_copy_settings(rdpSettings* dst, const rdpSettings* src);
|
|
||||||
BOOL proxy_data_shall_disconnect(proxyData* pdata);
|
BOOL proxy_data_shall_disconnect(proxyData* pdata);
|
||||||
void proxy_data_abort_connect(proxyData* pdata);
|
void proxy_data_abort_connect(proxyData* pdata);
|
||||||
|
|
||||||
/* server */
|
|
||||||
BOOL init_p_server_context(freerdp_peer* client);
|
|
||||||
|
|
||||||
#endif /* FREERDP_SERVER_PROXY_PFCONTEXT_H */
|
#endif /* FREERDP_SERVER_PROXY_PFCONTEXT_H */
|
||||||
|
@ -143,10 +143,10 @@ static BOOL pf_server_post_connect(freerdp_peer* client)
|
|||||||
ps = (pServerContext*)client->context;
|
ps = (pServerContext*)client->context;
|
||||||
pdata = ps->pdata;
|
pdata = ps->pdata;
|
||||||
|
|
||||||
pc = p_client_context_create(client->settings);
|
pc = pf_context_create_client_context(client->settings);
|
||||||
if (pc == NULL)
|
if (pc == NULL)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "pf_server_post_connect(): p_client_context_create failed!");
|
WLog_ERR(TAG, "pf_server_post_connect(): pf_context_create_client_context failed!");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,15 +209,10 @@ static DWORD WINAPI pf_server_handle_client(LPVOID arg)
|
|||||||
proxyConfig* config;
|
proxyConfig* config;
|
||||||
freerdp_peer* client = (freerdp_peer*)arg;
|
freerdp_peer* client = (freerdp_peer*)arg;
|
||||||
|
|
||||||
if (!init_p_server_context(client))
|
if (!pf_context_init_server_context(client))
|
||||||
goto out_free_peer;
|
goto out_free_peer;
|
||||||
|
|
||||||
ps = (pServerContext*)client->context;
|
ps = (pServerContext*)client->context;
|
||||||
if (!(ps->dynvcReady = CreateEvent(NULL, TRUE, FALSE, NULL)))
|
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "pf_server_post_connect(): CreateEvent failed!");
|
|
||||||
goto out_free_peer;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(pdata = ps->pdata = proxy_data_new()))
|
if (!(pdata = ps->pdata = proxy_data_new()))
|
||||||
{
|
{
|
||||||
@ -225,18 +220,15 @@ static DWORD WINAPI pf_server_handle_client(LPVOID arg)
|
|||||||
goto out_free_peer;
|
goto out_free_peer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pdata->ps = ps;
|
||||||
|
config = pdata->config = client->ContextExtra;
|
||||||
|
|
||||||
/* currently not supporting GDI orders */
|
/* currently not supporting GDI orders */
|
||||||
ZeroMemory(client->settings->OrderSupport, 32);
|
ZeroMemory(client->settings->OrderSupport, 32);
|
||||||
client->update->autoCalculateBitmapData = FALSE;
|
client->update->autoCalculateBitmapData = FALSE;
|
||||||
pdata->ps = ps;
|
|
||||||
/* keep configuration in proxyData */
|
client->settings->SupportMonitorLayoutPdu = TRUE;
|
||||||
pdata->config = client->ContextExtra;
|
|
||||||
config = pdata->config;
|
|
||||||
client->settings->UseMultimon = TRUE;
|
|
||||||
client->settings->AudioPlayback = FALSE;
|
|
||||||
client->settings->DeviceRedirection = TRUE;
|
|
||||||
client->settings->SupportGraphicsPipeline = config->GFX;
|
client->settings->SupportGraphicsPipeline = config->GFX;
|
||||||
client->settings->SupportDynamicChannels = TRUE;
|
|
||||||
client->settings->CertificateFile = _strdup("server.crt");
|
client->settings->CertificateFile = _strdup("server.crt");
|
||||||
client->settings->PrivateKeyFile = _strdup("server.key");
|
client->settings->PrivateKeyFile = _strdup("server.key");
|
||||||
client->settings->RdpKeyFile = _strdup("server.key");
|
client->settings->RdpKeyFile = _strdup("server.key");
|
||||||
@ -248,9 +240,6 @@ static DWORD WINAPI pf_server_handle_client(LPVOID arg)
|
|||||||
goto out_free_peer;
|
goto out_free_peer;
|
||||||
}
|
}
|
||||||
|
|
||||||
client->settings->SupportDisplayControl = config->DisplayControl;
|
|
||||||
client->settings->DynamicResolutionUpdate = config->DisplayControl;
|
|
||||||
client->settings->SupportMonitorLayoutPdu = TRUE;
|
|
||||||
client->settings->RdpSecurity = config->RdpSecurity;
|
client->settings->RdpSecurity = config->RdpSecurity;
|
||||||
client->settings->TlsSecurity = config->TlsSecurity;
|
client->settings->TlsSecurity = config->TlsSecurity;
|
||||||
client->settings->NlaSecurity = config->NlaSecurity;
|
client->settings->NlaSecurity = config->NlaSecurity;
|
||||||
|
Loading…
Reference in New Issue
Block a user