server/proxy: Code refactor

This commit is contained in:
kubistika 2019-05-26 15:33:28 +03:00
parent aa262d341d
commit 52e4baa949
5 changed files with 121 additions and 97 deletions

View File

@ -31,10 +31,10 @@ static PF_FILTER_RESULT demo_filter_mouse_event(connectionInfo* info, void* para
{
proxyMouseEventInfo* event_data = (proxyMouseEventInfo*) param;
if (event_data->x % 100 == 0)
{
return FILTER_DROP;
}
if (event_data->x % 100 == 0)
{
return FILTER_DROP;
}
return FILTER_PASS;
}

View File

@ -56,8 +56,7 @@ BOOL init_p_server_context(freerdp_peer* client)
return freerdp_peer_context_new(client);
}
rdpContext* p_client_context_create(rdpSettings* clientSettings,
char* host, DWORD port)
rdpContext* p_client_context_create(rdpSettings* clientSettings)
{
RDP_CLIENT_ENTRY_POINTS clientEntryPoints;
rdpContext* context;
@ -73,14 +72,12 @@ rdpContext* p_client_context_create(rdpSettings* clientSettings,
settings->Username = _strdup(clientSettings->Username);
settings->Password = _strdup(clientSettings->Password);
settings->Domain = _strdup(clientSettings->Domain);
settings->ServerHostname = host;
settings->ServerPort = port;
settings->SoftwareGdi = FALSE;
settings->RedirectClipboard = FALSE;
return context;
}
static void pf_context_connection_info_free(connectionInfo* info)
static void connection_info_free(connectionInfo* info)
{
free(info->TargetHostname);
free(info->ClientHostname);
@ -88,7 +85,7 @@ static void pf_context_connection_info_free(connectionInfo* info)
free(info);
}
proxyData* pf_context_proxy_data_new()
proxyData* proxy_data_new()
{
proxyData* pdata = calloc(1, sizeof(proxyData));
@ -105,11 +102,35 @@ proxyData* pf_context_proxy_data_new()
return NULL;
}
if (!(pdata->connectionClosed = CreateEvent(NULL, TRUE, FALSE, NULL)))
{
proxy_data_free(pdata);
return NULL;
}
return pdata;
}
void pf_context_proxy_data_free(proxyData* pdata)
BOOL proxy_data_set_connection_info(proxyData* pdata, rdpSettings* clientSettings,
const char* target)
{
pf_context_connection_info_free(pdata->info);
if (!(pdata->info->TargetHostname = _strdup(target)))
goto out_fail;
if (!(pdata->info->ClientHostname = _strdup(clientSettings->ClientHostname)))
goto out_fail;
if (!(pdata->info->Username = _strdup(clientSettings->Username)))
goto out_fail;
return TRUE;
out_fail:
proxy_data_free(pdata);
return FALSE;
}
void proxy_data_free(proxyData* pdata)
{
connection_info_free(pdata->info);
free(pdata);
}

View File

@ -31,7 +31,6 @@
#include "pf_server.h"
#include "pf_filters.h"
typedef struct proxy_data proxyData;
/**
@ -82,8 +81,10 @@ struct proxy_data
};
BOOL init_p_server_context(freerdp_peer* client);
rdpContext* p_client_context_create(rdpSettings* clientSettings, char* host, DWORD port);
proxyData* pf_context_proxy_data_new();
void pf_context_proxy_data_free(proxyData* pdata);
rdpContext* p_client_context_create(rdpSettings* clientSettings);
proxyData* proxy_data_new();
BOOL proxy_data_set_connection_info(proxyData* pdata, rdpSettings* clientSettings,
const char* target);
void proxy_data_free(proxyData* pdata);
#endif /* FREERDP_SERVER_PROXY_PFCONTEXT_H */

View File

@ -153,12 +153,7 @@ BOOL pf_filters_register_new(filters_list* list, const char* module_path, const
HMODULE handle = NULL;
filterInitFn fn;
if (list == NULL)
{
WLog_ERR(TAG, "pf_filters_register_new(): list == NULL");
goto error;
}
assert(list != NULL);
handle = LoadLibraryA(module_path);
if (handle == NULL)

View File

@ -71,7 +71,7 @@ static void pf_server_handle_client_disconnection(freerdp_peer* client)
CloseHandle(ps->thread);
}
static BOOL pf_server_parse_target_from_routing_token(freerdp_peer* client,
static BOOL pf_server_parse_target_from_routing_token(rdpContext* context,
char** target, DWORD* port)
{
#define TARGET_MAX (100)
@ -80,7 +80,7 @@ static BOOL pf_server_parse_target_from_routing_token(freerdp_peer* client,
size_t len;
const size_t prefix_len = strlen(ROUTING_TOKEN_PREFIX);
DWORD routing_token_length;
const char* routing_token = freerdp_nego_get_routing_token(client->context, &routing_token_length);
const char* routing_token = freerdp_nego_get_routing_token(context, &routing_token_length);
if (routing_token == NULL)
{
@ -124,6 +124,28 @@ static BOOL pf_server_parse_target_from_routing_token(freerdp_peer* client,
return TRUE;
}
static BOOL pf_server_get_target_info(rdpContext* context, rdpSettings* settings,
proxyConfig* config)
{
WLog_INFO(TAG, "pf_server_get_target_info: UseLoadBalanceInfo = %d", config->UseLoadBalanceInfo);
if (config->UseLoadBalanceInfo)
return pf_server_parse_target_from_routing_token(context, &settings->ServerHostname,
&settings->ServerPort);
/* use hardcoded target info from configuration */
if (!(settings->ServerHostname = _strdup(config->TargetHost)))
{
WLog_DBG(TAG, "pf_server_get_target_info(): strdup failed!");
return FALSE;
}
settings->ServerPort = config->TargetPort > 0 ? 3389 : settings->ServerPort;
WLog_INFO(TAG, "Using target host from config: %s:%i", settings->ServerHostname,
settings->ServerPort);
return TRUE;
}
/* Event callbacks */
/**
* This callback is called when the entire connection sequence is done (as
@ -134,45 +156,35 @@ static BOOL pf_server_parse_target_from_routing_token(freerdp_peer* client,
*/
static BOOL pf_server_post_connect(freerdp_peer* client)
{
proxyConfig* config;
pServerContext* ps;
pClientContext* pc;
rdpContext* pc;
proxyData* pdata;
char* host = NULL;
DWORD port = 3389; /* default port */
ps = (pServerContext*)client->context;
pdata = ps->pdata;
config = pdata->config;
if (config->UseLoadBalanceInfo)
{
if (!pf_server_parse_target_from_routing_token(client, &host, &port))
{
WLog_ERR(TAG, "pf_server_parse_target_from_routing_token failed!");
return FALSE;
}
}
else
{
/* use hardcoded target info from configuration */
host = _strdup(config->TargetHost);
port = config->TargetPort > 0 ? config->TargetPort : port;
WLog_DBG(TAG, "Using hardcoded target host: %s:%i", host, port);
}
pc = p_client_context_create(client->settings);
pc = (pClientContext*) p_client_context_create(client->settings, host, port);
/* keep both sides of the connection in pdata */
pc->pdata = ps->pdata;
pdata->info->TargetHostname = _strdup(host);
pdata->info->Username = _strdup(client->settings->Username);
pdata->pc = pc;
pdata->ps = ps;
pdata->connectionClosed = CreateEvent(NULL, TRUE, FALSE, NULL);
((pClientContext*)pc)->pdata = ps->pdata;
pdata->pc = (pClientContext*)pc;
if (!pf_server_get_target_info(client->context, pc->settings, pdata->config))
{
WLog_ERR(TAG, "pf_server_post_connect(): pf_server_get_target_info failed!");
return FALSE;
}
if (!proxy_data_set_connection_info(pdata, client->settings, pc->settings->ServerHostname))
{
WLog_ERR(TAG, "proxy_data_set_connection_info failed!");
return FALSE;
}
pf_server_rdpgfx_init(ps);
/* Start a proxy's client in it's own thread */
if (!(ps->thread = CreateThread(NULL, 0, pf_client_start, (rdpContext*) pc, 0,
NULL)))
if (!(ps->thread = CreateThread(NULL, 0, pf_client_start, pc, 0, NULL)))
{
WLog_ERR(TAG, "CreateThread failed!");
return FALSE;
@ -203,26 +215,25 @@ static DWORD WINAPI pf_server_handle_client(LPVOID arg)
rdpContext* pc;
proxyData* pdata;
proxyConfig* config;
freerdp_peer* client = (freerdp_peer*) arg;
freerdp_peer* client = (freerdp_peer*)arg;
if (!init_p_server_context(client))
goto out_free_peer;
ps = (pServerContext*)client->context;
if (!(ps->dynvcReady = CreateEvent(NULL, TRUE, FALSE, NULL)))
{
freerdp_peer_free(client);
return 0;
WLog_ERR(TAG, "pf_server_post_connect(): CreateEvent failed!");
goto out_free_peer;
}
ps = (pServerContext*) client->context;
ps->dynvcReady = CreateEvent(NULL, TRUE, FALSE, NULL);
pdata = pf_context_proxy_data_new();
if (pdata == NULL)
if (!(pdata = ps->pdata = proxy_data_new()))
{
WLog_ERR(TAG, "pf_context_proxy_data_new failed!");
return 0;
WLog_ERR(TAG, "pf_server_post_connect(): proxy_data_new failed!");
goto out_free_peer;
}
pdata->info->ClientHostname = _strdup(client->hostname);
ps->pdata = pdata;
pdata->ps = ps;
/* keep configuration in proxyData */
pdata->config = client->ContextExtra;
config = pdata->config;
@ -232,12 +243,11 @@ static DWORD WINAPI pf_server_handle_client(LPVOID arg)
client->settings->PrivateKeyFile = _strdup("server.key");
client->settings->RdpKeyFile = _strdup("server.key");
if (!client->settings->CertificateFile || !client->settings->PrivateKeyFile
|| !client->settings->RdpKeyFile)
if (!client->settings->CertificateFile || !client->settings->PrivateKeyFile ||
!client->settings->RdpKeyFile)
{
WLog_ERR(TAG, "Memory allocation failed (strdup)");
freerdp_peer_free(client);
return 0;
goto out_free_peer;
}
client->settings->RdpSecurity = config->RdpSecurity;
@ -253,8 +263,7 @@ static DWORD WINAPI pf_server_handle_client(LPVOID arg)
pf_server_register_update_callbacks(client->update);
client->settings->MultifragMaxRequestSize = 0xFFFFFF; /* FIXME */
client->Initialize(client);
WLog_INFO(TAG, "Client connected: %s",
client->local ? "(local)" : client->hostname);
WLog_INFO(TAG, "Client connected: %s", client->local ? "(local)" : client->hostname);
/* Main client event handling loop */
ChannelEvent = WTSVirtualChannelManagerGetEventHandle(ps->vcm);
@ -262,8 +271,7 @@ static DWORD WINAPI pf_server_handle_client(LPVOID arg)
{
eventCount = 0;
{
tmp = client->GetEventHandles(client, &eventHandles[eventCount],
32 - eventCount);
tmp = client->GetEventHandles(client, &eventHandles[eventCount], 32 - eventCount);
if (tmp == 0)
{
@ -301,28 +309,28 @@ static DWORD WINAPI pf_server_handle_client(LPVOID arg)
switch (WTSVirtualChannelManagerGetDrdynvcState(ps->vcm))
{
/* Dynamic channel status may have been changed after processing */
case DRDYNVC_STATE_NONE:
/* Dynamic channel status may have been changed after processing */
case DRDYNVC_STATE_NONE:
/* Initialize drdynvc channel */
if (!WTSVirtualChannelManagerCheckFileDescriptor(ps->vcm))
{
WLog_ERR(TAG, "Failed to initialize drdynvc channel");
goto fail;
}
/* Initialize drdynvc channel */
if (!WTSVirtualChannelManagerCheckFileDescriptor(ps->vcm))
{
WLog_ERR(TAG, "Failed to initialize drdynvc channel");
goto fail;
}
break;
break;
case DRDYNVC_STATE_READY:
if (WaitForSingleObject(ps->dynvcReady, 0) == WAIT_TIMEOUT)
{
SetEvent(ps->dynvcReady);
}
case DRDYNVC_STATE_READY:
if (WaitForSingleObject(ps->dynvcReady, 0) == WAIT_TIMEOUT)
{
SetEvent(ps->dynvcReady);
}
break;
break;
default:
break;
default:
break;
}
}
@ -333,24 +341,23 @@ fail:
pf_server_handle_client_disconnection(client);
}
pc = (rdpContext*) pdata->pc;
pc = (rdpContext*)pdata->pc;
freerdp_client_stop(pc);
pf_context_proxy_data_free(pdata);
proxy_data_free(pdata);
freerdp_client_context_free(pc);
client->Disconnect(client);
out_free_peer:
freerdp_peer_context_free(client);
freerdp_peer_free(client);
return 0;
}
static BOOL pf_server_client_connected(freerdp_listener* listener,
freerdp_peer* client)
static BOOL pf_server_client_connected(freerdp_listener* listener, freerdp_peer* client)
{
HANDLE hThread;
client->ContextExtra = listener->info;
if (!(hThread = CreateThread(NULL, 0, pf_server_handle_client,
(void*) client, 0, NULL)))
if (!(hThread = CreateThread(NULL, 0, pf_server_handle_client, (void*)client, 0, NULL)))
return FALSE;
CloseHandle(hThread);
@ -414,7 +421,7 @@ int pf_server_start(proxyConfig* config)
}
/* Determine filepath for local socket */
sprintf_s(localSockName, sizeof(localSockName), "proxy.%"PRIu16"", config->Port);
sprintf_s(localSockName, sizeof(localSockName), "proxy.%" PRIu16 "", config->Port);
localSockPath = GetKnownSubPath(KNOWN_PATH_TEMP, localSockName);
if (!localSockPath)