libfreerdp-core: improve TSG memory cleanup

This commit is contained in:
Marc-André Moreau 2012-12-12 20:02:56 -05:00
parent 892a55073e
commit 102abcbef2
9 changed files with 124 additions and 43 deletions

View File

@ -104,6 +104,7 @@ BOOL rdp_client_connect(rdpRdp* rdp)
cookie[cookie_length] = '\0';
nego_set_cookie(rdp->nego, cookie);
free(cookie);
settings->RdpSecurity = TRUE;
settings->TlsSecurity = FALSE;

View File

@ -191,6 +191,7 @@ int rpc_ncacn_http_recv_out_channel_response(rdpRpc* rpc)
HttpResponse* http_response;
rdpNtlm* ntlm = rpc->NtlmHttpOut->ntlm;
printf("TlsOut: %p\n", rpc->TlsOut);
http_response = http_response_recv(rpc->TlsOut);
ntlm_token_data = NULL;

View File

@ -255,6 +255,7 @@ void ntlm_client_uninit(rdpNtlm* ntlm)
ntlm->table->FreeCredentialsHandle(&ntlm->credentials);
ntlm->table->FreeContextBuffer(ntlm->pPackageInfo);
ntlm->table->DeleteSecurityContext(&ntlm->context);
}
rdpNtlm* ntlm_new()

View File

@ -384,9 +384,6 @@ int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum)
if (request_pdu->opnum == TsProxySetupReceivePipeOpnum)
rpc->PipeCallId = request_pdu->call_id;
printf("Request CallId: %d OpNum: %d\n",
request_pdu->call_id, request_pdu->opnum);
request_pdu->stub_data = data;
offset = 24;
@ -585,9 +582,19 @@ rdpRpc* rpc_new(rdpTransport* transport)
void rpc_free(rdpRpc* rpc)
{
printf("rpc_free\n");
if (rpc != NULL)
{
ntlm_free(rpc->ntlm);
rpc_client_stop(rpc);
printf("rpc_client stopped\n");
if (rpc->State >= RPC_CLIENT_STATE_CONTEXT_NEGOTIATED)
{
ntlm_client_uninit(rpc->ntlm);
ntlm_free(rpc->ntlm);
}
ntlm_http_free(rpc->NtlmHttpIn);
ntlm_http_free(rpc->NtlmHttpOut);

View File

@ -152,7 +152,7 @@ int rpc_client_on_fragment_received_event(rdpRpc* rpc)
if (StubLength == 4)
{
printf("Ignoring TsProxySendToServer Response\n");
//printf("Ignoring TsProxySendToServer Response\n");
rpc_client_fragment_pool_return(rpc, fragment);
return 0;
}
@ -177,7 +177,7 @@ int rpc_client_on_fragment_received_event(rdpRpc* rpc)
if (rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow < (rpc->ReceiveWindow / 2))
{
printf("Sending Flow Control Ack PDU\n");
//printf("Sending Flow Control Ack PDU\n");
rts_send_flow_control_ack_pdu(rpc);
}
@ -462,31 +462,38 @@ static void rpc_fragment_free(wStream* fragment)
int rpc_client_new(rdpRpc* rpc)
{
rpc->client = (RpcClient*) malloc(sizeof(RpcClient));
RpcClient* client = NULL;
rpc->client->Thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) rpc_client_thread,
rpc, CREATE_SUSPENDED, NULL);
client = (RpcClient*) malloc(sizeof(RpcClient));
rpc->client->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
rpc->client->PduSentEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (client)
{
client->Thread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) rpc_client_thread,
rpc, CREATE_SUSPENDED, NULL);
rpc->client->SendQueue = Queue_New(TRUE, -1, -1);
Queue_Object(rpc->client->SendQueue)->fnObjectFree = (OBJECT_FREE_FN) rpc_pdu_free;
client->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
client->PduSentEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
rpc->client->ReceivePool = Queue_New(TRUE, -1, -1);
rpc->client->ReceiveQueue = Queue_New(TRUE, -1, -1);
Queue_Object(rpc->client->ReceivePool)->fnObjectFree = (OBJECT_FREE_FN) rpc_pdu_free;
Queue_Object(rpc->client->ReceiveQueue)->fnObjectFree = (OBJECT_FREE_FN) rpc_pdu_free;
client->SendQueue = Queue_New(TRUE, -1, -1);
Queue_Object(client->SendQueue)->fnObjectFree = (OBJECT_FREE_FN) rpc_pdu_free;
rpc->client->FragmentPool = Queue_New(TRUE, -1, -1);
rpc->client->FragmentQueue = Queue_New(TRUE, -1, -1);
client->ReceivePool = Queue_New(TRUE, -1, -1);
client->ReceiveQueue = Queue_New(TRUE, -1, -1);
Queue_Object(client->ReceivePool)->fnObjectFree = (OBJECT_FREE_FN) rpc_pdu_free;
Queue_Object(client->ReceiveQueue)->fnObjectFree = (OBJECT_FREE_FN) rpc_pdu_free;
Queue_Object(rpc->client->FragmentPool)->fnObjectFree = (OBJECT_FREE_FN) rpc_fragment_free;
Queue_Object(rpc->client->FragmentQueue)->fnObjectFree = (OBJECT_FREE_FN) rpc_fragment_free;
client->FragmentPool = Queue_New(TRUE, -1, -1);
client->FragmentQueue = Queue_New(TRUE, -1, -1);
rpc->client->ClientCallList = ArrayList_New(TRUE);
ArrayList_Object(rpc->client->ClientCallList)->fnObjectFree = (OBJECT_FREE_FN) rpc_client_call_free;
Queue_Object(client->FragmentPool)->fnObjectFree = (OBJECT_FREE_FN) rpc_fragment_free;
Queue_Object(client->FragmentQueue)->fnObjectFree = (OBJECT_FREE_FN) rpc_fragment_free;
client->ClientCallList = ArrayList_New(TRUE);
ArrayList_Object(client->ClientCallList)->fnObjectFree = (OBJECT_FREE_FN) rpc_client_call_free;
}
rpc->client = client;
return 0;
}
@ -502,27 +509,39 @@ int rpc_client_stop(rdpRpc* rpc)
{
SetEvent(rpc->client->StopEvent);
printf("rpc_client_stop waiting for thread\n");
WaitForSingleObject(rpc->client->Thread, INFINITE);
return 0;
}
int rpc_client_free(rdpRpc* rpc)
{
Queue_Clear(rpc->client->SendQueue);
Queue_Free(rpc->client->SendQueue);
RpcClient* client;
Queue_Clear(rpc->client->ReceivePool);
Queue_Free(rpc->client->ReceivePool);
client = rpc->client;
Queue_Clear(rpc->client->ReceiveQueue);
Queue_Free(rpc->client->ReceiveQueue);
printf("rpc_client_free\n");
ArrayList_Clear(rpc->client->ClientCallList);
ArrayList_Free(rpc->client->ClientCallList);
if (client)
{
Queue_Clear(client->SendQueue);
Queue_Free(client->SendQueue);
CloseHandle(rpc->client->StopEvent);
CloseHandle(rpc->client->PduSentEvent);
Queue_Clear(client->ReceivePool);
Queue_Free(client->ReceivePool);
free(rpc->client);
Queue_Clear(client->ReceiveQueue);
Queue_Free(client->ReceiveQueue);
ArrayList_Clear(client->ClientCallList);
ArrayList_Free(client->ClientCallList);
CloseHandle(client->StopEvent);
CloseHandle(client->PduSentEvent);
free(client);
}
return 0;
}

View File

@ -177,7 +177,7 @@ BOOL TsProxyCreateTunnelWriteRequest(rdpTsg* tsg)
TSG_MESSAGING_CAP_REAUTH;
/*
* FIXME: Alternate Code Path
* Alternate Code Path
*
* Using reduced capabilities appears to trigger
* TSG_PACKET_TYPE_QUARENC_RESPONSE instead of TSG_PACKET_TYPE_CAPS_RESPONSE
@ -1104,6 +1104,33 @@ BOOL tsg_connect(rdpTsg* tsg, const char* hostname, UINT16 port)
return TRUE;
}
BOOL tsg_disconnect(rdpTsg* tsg)
{
printf("tsg_disconnect\n");
/**
* Gateway Shutdown Phase
*
* Client Server
* | |
* |-------------TsProxyCloseChannel Request---------->|
* | |
* |<-------TsProxySetupReceivePipe Final Response-----|
* |<-----------TsProxyCloseChannel Response-----------|
* | |
* |----TsProxyMakeTunnelCall Request (cancel async)-->|
* | |
* |<---TsProxyMakeTunnelCall Response (call async)----|
* |<---TsProxyMakeTunnelCall Response (cancel async)--|
* | |
* |--------------TsProxyCloseTunnel Request---------->|
* |<-------------TsProxyCloseTunnel Response----------|
* | |
*/
return TRUE;
}
int tsg_read(rdpTsg* tsg, BYTE* data, UINT32 length)
{
int CopyLength;
@ -1194,6 +1221,8 @@ rdpTsg* tsg_new(rdpTransport* transport)
void tsg_free(rdpTsg* tsg)
{
printf("tsg_free\n");
if (tsg != NULL)
{
free(tsg->MachineName);

View File

@ -303,6 +303,7 @@ typedef struct _TSG_PACKET
DWORD TsProxySendToServer(handle_t IDL_handle, BYTE pRpcMessage[], UINT32 count, UINT32* lengths);
BOOL tsg_connect(rdpTsg* tsg, const char* hostname, UINT16 port);
BOOL tsg_disconnect(rdpTsg* tsg);
int tsg_write(rdpTsg* tsg, BYTE* data, UINT32 length);
int tsg_read(rdpTsg* tsg, BYTE* data, UINT32 length);

View File

@ -75,10 +75,21 @@ void transport_attach(rdpTransport* transport, int sockfd)
BOOL transport_disconnect(rdpTransport* transport)
{
if (transport->layer == TRANSPORT_LAYER_TLS)
tls_disconnect(transport->TlsIn);
BOOL status = TRUE;
return tcp_disconnect(transport->TcpIn);
if (transport->layer == TRANSPORT_LAYER_TLS)
status &= tls_disconnect(transport->TlsIn);
if (transport->layer == TRANSPORT_LAYER_TSG)
{
tsg_disconnect(transport->tsg);
}
else
{
status &= tcp_disconnect(transport->TcpIn);
}
return status;
}
BOOL transport_connect_rdp(rdpTransport* transport)

View File

@ -370,17 +370,28 @@ void sspi_CopyAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity, SEC_WINNT_AUTH_IDE
}
}
static BOOL sspi_initialized = FALSE;
void sspi_GlobalInit()
{
SSL_load_error_strings();
SSL_library_init();
if (!sspi_initialized)
{
SSL_load_error_strings();
SSL_library_init();
sspi_ContextBufferAllocTableNew();
sspi_ContextBufferAllocTableNew();
sspi_initialized = TRUE;
}
}
void sspi_GlobalFinish()
{
sspi_ContextBufferAllocTableFree();
if (sspi_initialized)
{
sspi_ContextBufferAllocTableFree();
}
sspi_initialized = FALSE;
}
#ifndef WITH_NATIVE_SSPI