diff --git a/channels/client/CMakeLists.txt b/channels/client/CMakeLists.txt index 5733f5b5b..b337cf604 100644 --- a/channels/client/CMakeLists.txt +++ b/channels/client/CMakeLists.txt @@ -62,7 +62,6 @@ foreach(STATIC_MODULE ${CHANNEL_STATIC_CLIENT_MODULES}) if(CHANNEL_SUBSYSTEMS MATCHES "NOTFOUND") set(CHANNEL_SUBSYSTEMS "") endif() - message(STATUS "Channel: ${STATIC_MODULE_CHANNEL} Subsystems: ${CHANNEL_SUBSYSTEMS}") foreach(STATIC_SUBSYSTEM ${CHANNEL_SUBSYSTEMS}) if(${STATIC_SUBSYSTEM} MATCHES "^([^-]*)-(.*)") string(REGEX REPLACE "^([^-]*)-(.*)" "\\1" STATIC_SUBSYSTEM_NAME ${STATIC_SUBSYSTEM}) diff --git a/libfreerdp/core/gateway/rpc.c b/libfreerdp/core/gateway/rpc.c index aabc1be24..965ecae3a 100644 --- a/libfreerdp/core/gateway/rpc.c +++ b/libfreerdp/core/gateway/rpc.c @@ -268,8 +268,8 @@ int rpc_in_write(rdpRpc* rpc, BYTE* data, int length) #ifdef WITH_DEBUG_TSG rpc_pdu_header_print((rpcconn_hdr_t*) data); - printf("Sending PDU (length: %d)\n", length); - freerdp_hexdump(data, length); + printf("Sending PDU (length: %d)\n", FragBufferSize); + freerdp_hexdump(data, FragBufferSize); #endif status = tls_write_all(rpc->TlsIn, data, length); @@ -322,7 +322,9 @@ int rpc_recv_pdu_fragment(rdpRpc* rpc) int bytesRead = 0; rpcconn_hdr_t* header; - status = rpc_recv_pdu_header(rpc, rpc->buffer); + WaitForSingleObject(rpc->VirtualConnection->DefaultInChannel->Mutex, INFINITE); + + status = rpc_recv_pdu_header(rpc, rpc->FragBuffer); if (status < 1) { @@ -331,23 +333,19 @@ int rpc_recv_pdu_fragment(rdpRpc* rpc) } headerLength = status; - header = (rpcconn_hdr_t*) rpc->buffer; + header = (rpcconn_hdr_t*) rpc->FragBuffer; bytesRead += status; - -#ifdef WITH_DEBUG_RPC - rpc_pdu_header_print(header); -#endif - if (header->common.frag_length > rpc->length) + if (header->common.frag_length > rpc->FragBufferSize) { - rpc->length = header->common.frag_length; - rpc->buffer = (BYTE*) realloc(rpc->buffer, rpc->length); - header = (rpcconn_hdr_t*) rpc->buffer; + rpc->FragBufferSize = header->common.frag_length; + rpc->FragBuffer = (BYTE*) realloc(rpc->FragBuffer, rpc->FragBufferSize); + header = (rpcconn_hdr_t*) rpc->FragBuffer; } while (bytesRead < header->common.frag_length) { - status = rpc_out_read(rpc, &rpc->buffer[bytesRead], header->common.frag_length - bytesRead); + status = rpc_out_read(rpc, &rpc->FragBuffer[bytesRead], header->common.frag_length - bytesRead); if (status < 0) { @@ -358,6 +356,8 @@ int rpc_recv_pdu_fragment(rdpRpc* rpc) bytesRead += status; } + ReleaseMutex(rpc->VirtualConnection->DefaultInChannel->Mutex); + if (header->common.ptype == PTYPE_RTS) /* RTS PDU */ { if (rpc->VirtualConnection->State < VIRTUAL_CONNECTION_STATE_OPENED) @@ -386,13 +386,14 @@ int rpc_recv_pdu_fragment(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); } #ifdef WITH_DEBUG_RPC - printf("rpc_recv_pdu: length: %d\n", header->common.frag_length); - freerdp_hexdump(rpc->buffer, header->common.frag_length); + rpc_pdu_header_print((rpcconn_hdr_t*) header); + printf("rpc_recv_pdu_fragment: length: %d\n", header->common.frag_length); + freerdp_hexdump(rpc->FragBuffer, header->common.frag_length); printf("\n"); #endif @@ -408,7 +409,17 @@ int rpc_recv_pdu(rdpRpc* rpc) status = rpc_recv_pdu_fragment(rpc); - header = (rpcconn_hdr_t*) rpc->buffer; + if (rpc->State < RPC_CLIENT_STATE_CONTEXT_NEGOTIATED) + { + rpc->pdu->Flags = 0; + rpc->pdu->Buffer = rpc->FragBuffer; + rpc->pdu->Size = rpc->FragBufferSize; + rpc->pdu->Length = status; + + return status; + } + + header = (rpcconn_hdr_t*) rpc->FragBuffer; if (header->common.ptype != PTYPE_RESPONSE) { @@ -416,19 +427,19 @@ int rpc_recv_pdu(rdpRpc* rpc) return -1; } - if (!rpc_get_stub_data_info(rpc, rpc->buffer, &StubOffset, &StubLength)) + if (!rpc_get_stub_data_info(rpc, rpc->FragBuffer, &StubOffset, &StubLength)) { printf("rpc_recv_pdu: expected stub\n"); return -1; } - if (header->response.alloc_hint > rpc->StubSize) + if (header->response.alloc_hint > rpc->StubBufferSize) { - rpc->StubSize = header->response.alloc_hint; - rpc->StubBuffer = (BYTE*) realloc(rpc->StubBuffer, rpc->StubSize); + rpc->StubBufferSize = header->response.alloc_hint; + rpc->StubBuffer = (BYTE*) realloc(rpc->StubBuffer, rpc->StubBufferSize); } - CopyMemory(&rpc->StubBuffer[rpc->StubOffset], &rpc->buffer[StubOffset], StubLength); + CopyMemory(&rpc->StubBuffer[rpc->StubOffset], &rpc->FragBuffer[StubOffset], StubLength); rpc->StubOffset += StubLength; rpc->StubFragCount++; @@ -450,13 +461,18 @@ int rpc_recv_pdu(rdpRpc* rpc) rpc->StubOffset = 0; rpc->StubFragCount = 0; + rpc->pdu->Flags = RPC_PDU_FLAG_STUB; + rpc->pdu->Buffer = rpc->StubBuffer; + rpc->pdu->Size = rpc->StubBufferSize; + rpc->pdu->Length = rpc->StubLength; + return rpc->StubLength; } return rpc_recv_pdu(rpc); } -int rpc_tsg_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum) +int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum) { BYTE* buffer; UINT32 offset; @@ -550,9 +566,6 @@ int rpc_tsg_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum) rpc_send_enqueue_pdu(rpc, buffer, request_pdu->frag_length); - WaitForSingleObject(rpc->client->PduSentEvent, INFINITE); - ResetEvent(rpc->client->PduSentEvent); - return length; } @@ -561,6 +574,8 @@ BOOL rpc_connect(rdpRpc* rpc) rpc->TlsIn = rpc->transport->TlsIn; rpc->TlsOut = rpc->transport->TlsOut; + rpc_client_start(rpc); + if (!rts_connect(rpc)) { printf("rts_connect error!\n"); @@ -585,6 +600,7 @@ void rpc_client_virtual_connection_init(rdpRpc* rpc, RpcVirtualConnection* conne connection->DefaultInChannel->SenderAvailableWindow = rpc->ReceiveWindow; connection->DefaultInChannel->PingOriginator.ConnectionTimeout = 30; connection->DefaultInChannel->PingOriginator.KeepAliveInterval = 0; + connection->DefaultInChannel->Mutex = CreateMutex(NULL, FALSE, NULL); connection->DefaultOutChannel->State = CLIENT_OUT_CHANNEL_STATE_INITIAL; connection->DefaultOutChannel->BytesReceived = 0; @@ -592,6 +608,7 @@ void rpc_client_virtual_connection_init(rdpRpc* rpc, RpcVirtualConnection* conne connection->DefaultOutChannel->ReceiveWindow = rpc->ReceiveWindow; connection->DefaultOutChannel->ReceiveWindowSize = rpc->ReceiveWindow; connection->DefaultOutChannel->AvailableWindowAdvertised = rpc->ReceiveWindow; + connection->DefaultOutChannel->Mutex = CreateMutex(NULL, FALSE, NULL); } RpcVirtualConnection* rpc_client_virtual_connection_new(rdpRpc* rpc) @@ -675,14 +692,14 @@ rdpRpc* rpc_new(rdpTransport* transport) rpc_ntlm_http_init_channel(rpc, rpc->NtlmHttpIn, TSG_CHANNEL_IN); rpc_ntlm_http_init_channel(rpc, rpc->NtlmHttpOut, TSG_CHANNEL_OUT); - rpc->length = 20; - rpc->buffer = (BYTE*) malloc(rpc->length); + rpc->FragBufferSize = 20; + rpc->FragBuffer = (BYTE*) malloc(rpc->FragBufferSize); rpc->StubOffset = 0; - rpc->StubSize = 20; + rpc->StubBufferSize = 20; rpc->StubLength = 0; rpc->StubFragCount = 0; - rpc->StubBuffer = (BYTE*) malloc(rpc->length); + rpc->StubBuffer = (BYTE*) malloc(rpc->FragBufferSize); rpc->rpc_vers = 5; rpc->rpc_vers_minor = 0; @@ -696,9 +713,14 @@ rdpRpc* rpc_new(rdpTransport* transport) rpc->max_xmit_frag = 0x0FF8; rpc->max_recv_frag = 0x0FF8; + rpc->pdu = (RPC_PDU*) _aligned_malloc(sizeof(RPC_PDU), MEMORY_ALLOCATION_ALIGNMENT); + rpc->SendQueue = (PSLIST_HEADER) _aligned_malloc(sizeof(SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT); InitializeSListHead(rpc->SendQueue); + rpc->ReceiveQueue = (PSLIST_HEADER) _aligned_malloc(sizeof(SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT); + InitializeSListHead(rpc->ReceiveQueue); + rpc->ReceiveWindow = 0x00010000; rpc->ChannelLifetime = 0x40000000; @@ -713,7 +735,9 @@ rdpRpc* rpc_new(rdpTransport* transport) rpc->call_id = 1; - rpc_client_start(rpc); + rpc_client_new(rpc); + + rpc->client->SynchronousSend = TRUE; } return rpc; @@ -723,18 +747,24 @@ void rpc_free(rdpRpc* rpc) { if (rpc != NULL) { - RPC_PDU_ENTRY* PduEntry; + RPC_PDU* PduEntry; ntlm_http_free(rpc->NtlmHttpIn); ntlm_http_free(rpc->NtlmHttpOut); - while ((PduEntry = (RPC_PDU_ENTRY*) InterlockedPopEntrySList(rpc->SendQueue)) != NULL) - _aligned_free(PduEntry); + _aligned_free(rpc->pdu); + while ((PduEntry = (RPC_PDU*) InterlockedPopEntrySList(rpc->SendQueue)) != NULL) + _aligned_free(PduEntry); _aligned_free(rpc->SendQueue); + while ((PduEntry = (RPC_PDU*) InterlockedPopEntrySList(rpc->ReceiveQueue)) != NULL) + _aligned_free(PduEntry); + _aligned_free(rpc->ReceiveQueue); + rpc_client_virtual_connection_free(rpc->VirtualConnection); rpc_virtual_connection_cookie_table_free(rpc->VirtualConnectionCookieTable); + free(rpc); } } diff --git a/libfreerdp/core/gateway/rpc.h b/libfreerdp/core/gateway/rpc.h index 1ae147bb2..214481a92 100644 --- a/libfreerdp/core/gateway/rpc.h +++ b/libfreerdp/core/gateway/rpc.h @@ -602,6 +602,8 @@ struct rpc_in_channel CLIENT_IN_CHANNEL_STATE State; + HANDLE Mutex; + UINT32 PlugState; void* SendQueue; UINT32 BytesSent; @@ -633,6 +635,8 @@ struct rpc_out_channel CLIENT_OUT_CHANNEL_STATE State; + HANDLE Mutex; + UINT32 ReceiveWindow; UINT32 ReceiveWindowSize; UINT32 ReceiverAvailableWindow; @@ -693,12 +697,16 @@ struct rpc_virtual_connection_cookie_table }; typedef struct rpc_virtual_connection_cookie_table RpcVirtualConnectionCookieTable; -typedef struct _RPC_PDU_ENTRY +#define RPC_PDU_FLAG_STUB 0x00000001 + +typedef struct _RPC_PDU { SLIST_ENTRY ItemEntry; BYTE* Buffer; + UINT32 Size; UINT32 Length; -} RPC_PDU_ENTRY, *PRPC_PDU_ENTRY; + DWORD Flags; +} RPC_PDU, *PRPC_PDU; struct rpc_client { @@ -707,6 +715,11 @@ struct rpc_client HANDLE PduSentEvent; HANDLE SendSemaphore; + BOOL SynchronousSend; + + HANDLE PduReceivedEvent; + HANDLE ReceiveSemaphore; + BOOL SynchronousReceive; }; typedef struct rpc_client RpcClient; @@ -731,11 +744,13 @@ struct rdp_rpc UINT32 call_id; UINT32 pipe_call_id; - BYTE* buffer; - UINT32 length; + RPC_PDU* pdu; + + BYTE* FragBuffer; + UINT32 FragBufferSize; BYTE* StubBuffer; - UINT32 StubSize; + UINT32 StubBufferSize; UINT32 StubLength; UINT32 StubOffset; UINT32 StubFragCount; @@ -748,6 +763,7 @@ struct rdp_rpc UINT16 max_recv_frag; PSLIST_HEADER SendQueue; + PSLIST_HEADER ReceiveQueue; UINT32 ReceiveWindow; @@ -778,7 +794,7 @@ int rpc_recv_pdu_header(rdpRpc* rpc, BYTE* header); int rpc_recv_pdu_fragment(rdpRpc* rpc); int rpc_recv_pdu(rdpRpc* rpc); -int rpc_tsg_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum); +int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum); rdpRpc* rpc_new(rdpTransport* transport); void rpc_free(rdpRpc* rpc); diff --git a/libfreerdp/core/gateway/rpc_bind.c b/libfreerdp/core/gateway/rpc_bind.c index 1b849aac9..3fa4b0ce0 100644 --- a/libfreerdp/core/gateway/rpc_bind.c +++ b/libfreerdp/core/gateway/rpc_bind.c @@ -217,11 +217,11 @@ int rpc_recv_bind_ack_pdu(rdpRpc* rpc) BYTE* auth_data; rpcconn_hdr_t* header; - status = rpc_recv_pdu_fragment(rpc); + status = rpc_recv_pdu(rpc); if (status > 0) { - header = (rpcconn_hdr_t*) rpc->buffer; + header = (rpcconn_hdr_t*) rpc->FragBuffer; rpc->max_recv_frag = header->bind_ack.max_xmit_frag; rpc->max_xmit_frag = header->bind_ack.max_recv_frag; @@ -229,7 +229,7 @@ int rpc_recv_bind_ack_pdu(rdpRpc* rpc) rpc->ntlm->inputBuffer.cbBuffer = header->common.auth_length; rpc->ntlm->inputBuffer.pvBuffer = malloc(header->common.auth_length); - auth_data = rpc->buffer + (header->common.frag_length - header->common.auth_length); + auth_data = rpc->FragBuffer + (header->common.frag_length - header->common.auth_length); CopyMemory(rpc->ntlm->inputBuffer.pvBuffer, auth_data, header->common.auth_length); ntlm_authenticate(rpc->ntlm); diff --git a/libfreerdp/core/gateway/rpc_client.c b/libfreerdp/core/gateway/rpc_client.c index 0c5dad6ce..28bcbde6f 100644 --- a/libfreerdp/core/gateway/rpc_client.c +++ b/libfreerdp/core/gateway/rpc_client.c @@ -33,29 +33,39 @@ int rpc_send_enqueue_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length) { - RPC_PDU_ENTRY* PduEntry; + RPC_PDU* pdu; - PduEntry = (RPC_PDU_ENTRY*) _aligned_malloc(sizeof(RPC_PDU_ENTRY), MEMORY_ALLOCATION_ALIGNMENT); - PduEntry->Buffer = buffer; - PduEntry->Length = length; + pdu = (RPC_PDU*) _aligned_malloc(sizeof(RPC_PDU), MEMORY_ALLOCATION_ALIGNMENT); + pdu->Buffer = buffer; + pdu->Length = length; - InterlockedPushEntrySList(rpc->SendQueue, &(PduEntry->ItemEntry)); + InterlockedPushEntrySList(rpc->SendQueue, &(pdu->ItemEntry)); ReleaseSemaphore(rpc->client->SendSemaphore, 1, NULL); + if (rpc->client->SynchronousSend) + { + WaitForSingleObject(rpc->client->PduSentEvent, INFINITE); + ResetEvent(rpc->client->PduSentEvent); + } + return 0; } int rpc_send_dequeue_pdu(rdpRpc* rpc) { int status; - RPC_PDU_ENTRY* PduEntry; + RPC_PDU* pdu; - PduEntry = (RPC_PDU_ENTRY*) InterlockedPopEntrySList(rpc->SendQueue); + pdu = (RPC_PDU*) InterlockedPopEntrySList(rpc->SendQueue); - if (!PduEntry) + if (!pdu) return 0; - status = rpc_in_write(rpc, PduEntry->Buffer, PduEntry->Length); + WaitForSingleObject(rpc->VirtualConnection->DefaultInChannel->Mutex, INFINITE); + + status = rpc_in_write(rpc, pdu->Buffer, pdu->Length); + + ReleaseMutex(rpc->VirtualConnection->DefaultInChannel->Mutex); /* * This protocol specifies that only RPC PDUs are subject to the flow control abstract @@ -66,41 +76,102 @@ int rpc_send_dequeue_pdu(rdpRpc* rpc) rpc->VirtualConnection->DefaultInChannel->BytesSent += status; rpc->VirtualConnection->DefaultInChannel->SenderAvailableWindow -= status; - free(PduEntry->Buffer); - _aligned_free(PduEntry); + free(pdu->Buffer); + _aligned_free(pdu); - SetEvent(rpc->client->PduSentEvent); + if (rpc->client->SynchronousSend) + SetEvent(rpc->client->PduSentEvent); return status; } +int rpc_recv_enqueue_pdu(rdpRpc* rpc) +{ + int status; + RPC_PDU* pdu; + + status = rpc_recv_pdu(rpc); + + if (status <= 0) + { + printf("rpc_recv_enqueue_pdu error\n"); + return -1; + } + + pdu = rpc->pdu; + rpc->pdu = (RPC_PDU*) _aligned_malloc(sizeof(RPC_PDU), MEMORY_ALLOCATION_ALIGNMENT); + + if (pdu->Flags & RPC_PDU_FLAG_STUB) + { + rpc->StubBufferSize = rpc->max_recv_frag; + rpc->StubBuffer = (BYTE*) malloc(rpc->StubBufferSize); + } + else + { + rpc->FragBufferSize = rpc->max_recv_frag; + rpc->FragBuffer = (BYTE*) malloc(rpc->FragBufferSize); + } + + InterlockedPushEntrySList(rpc->ReceiveQueue, &(pdu->ItemEntry)); + ReleaseSemaphore(rpc->client->ReceiveSemaphore, 1, NULL); + + if (rpc->client->SynchronousReceive) + { + WaitForSingleObject(rpc->client->PduReceivedEvent, INFINITE); + ResetEvent(rpc->client->PduReceivedEvent); + } + + return 0; +} + +int rpc_recv_dequeue_pdu(rdpRpc* rpc) +{ + if (rpc->client->SynchronousReceive) + SetEvent(rpc->client->PduReceivedEvent); + + return 0; +} + static void* rpc_client_thread(void* arg) { rdpRpc* rpc; DWORD status; DWORD nCount; - HANDLE events[2]; + HANDLE events[3]; + HANDLE ReadEvent; rpc = (rdpRpc*) arg; + ReadEvent = CreateFileDescriptorEvent(NULL, TRUE, FALSE, rpc->TlsOut->sockfd); + nCount = 0; events[nCount++] = rpc->client->StopEvent; events[nCount++] = rpc->client->SendSemaphore; + events[nCount++] = ReadEvent; while (1) { status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); if (WaitForSingleObject(rpc->client->StopEvent, 0) == WAIT_OBJECT_0) + { break; + } + + if (WaitForSingleObject(ReadEvent, 0) == WAIT_OBJECT_0) + { + + } rpc_send_dequeue_pdu(rpc); } + CloseHandle(ReadEvent); + return NULL; } -int rpc_client_start(rdpRpc* rpc) +int rpc_client_new(rdpRpc* rpc) { rpc->client = (RpcClient*) malloc(sizeof(RpcClient)); @@ -112,6 +183,11 @@ int rpc_client_start(rdpRpc* rpc) rpc->client->SendSemaphore = CreateSemaphore(NULL, 0, 64, NULL); rpc->client->PduSentEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + return 0; +} + +int rpc_client_start(rdpRpc* rpc) +{ ResumeThread(rpc->client->Thread); return 0; diff --git a/libfreerdp/core/gateway/rpc_client.h b/libfreerdp/core/gateway/rpc_client.h index 113e69bcd..5a3deedda 100644 --- a/libfreerdp/core/gateway/rpc_client.h +++ b/libfreerdp/core/gateway/rpc_client.h @@ -27,6 +27,7 @@ int rpc_send_enqueue_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length); int rpc_send_dequeue_pdu(rdpRpc* rpc); +int rpc_client_new(rdpRpc* rpc); int rpc_client_start(rdpRpc* rpc); #endif /* FREERDP_CORE_RPC_CLIENT_H */ diff --git a/libfreerdp/core/gateway/rts.c b/libfreerdp/core/gateway/rts.c index 05a9aba15..5c9df9098 100644 --- a/libfreerdp/core/gateway/rts.c +++ b/libfreerdp/core/gateway/rts.c @@ -173,12 +173,12 @@ BOOL rts_connect(rdpRpc* rpc) * */ - status = rts_recv_pdu(rpc); + status = rpc_recv_pdu(rpc); if (status < 1) return FALSE; - rts = (rpcconn_rts_hdr_t*) rpc->buffer; + rts = (rpcconn_rts_hdr_t*) rpc->FragBuffer; if (!rts_match_pdu_signature(rpc, &RTS_PDU_CONN_A3_SIGNATURE, rts)) { @@ -186,7 +186,7 @@ BOOL rts_connect(rdpRpc* rpc) return FALSE; } - rts_recv_CONN_A3_pdu(rpc, rpc->buffer, rpc->length); + rts_recv_CONN_A3_pdu(rpc, rpc->FragBuffer, rpc->FragBufferSize); rpc->VirtualConnection->State = VIRTUAL_CONNECTION_STATE_WAIT_C2; DEBUG_RTS("VIRTUAL_CONNECTION_STATE_WAIT_C2"); @@ -212,12 +212,12 @@ BOOL rts_connect(rdpRpc* rpc) * */ - status = rts_recv_pdu(rpc); + status = rpc_recv_pdu(rpc); if (status < 1) return FALSE; - rts = (rpcconn_rts_hdr_t*) rpc->buffer; + rts = (rpcconn_rts_hdr_t*) rpc->FragBuffer; if (!rts_match_pdu_signature(rpc, &RTS_PDU_CONN_C2_SIGNATURE, rts)) { @@ -225,7 +225,7 @@ BOOL rts_connect(rdpRpc* rpc) return FALSE; } - rts_recv_CONN_C2_pdu(rpc, rpc->buffer, rpc->length); + rts_recv_CONN_C2_pdu(rpc, rpc->FragBuffer, rpc->FragBufferSize); rpc->VirtualConnection->State = VIRTUAL_CONNECTION_STATE_OPENED; DEBUG_RTS("VIRTUAL_CONNECTION_STATE_OPENED"); @@ -952,35 +952,13 @@ int rts_command_length(rdpRpc* rpc, UINT32 CommandType, BYTE* buffer, UINT32 len return CommandLength; } -int rts_recv_pdu(rdpRpc* rpc) -{ - int status; - rpcconn_rts_hdr_t* rts; - - status = rpc_recv_pdu_fragment(rpc); - - if (status > 0) - { - rts = (rpcconn_rts_hdr_t*) rpc->buffer; - - if (rts->ptype != PTYPE_RTS) - { - printf("rts_recv_pdu: Unexpected type 0x%02X, Expected: PTYPE_RTS (0x%02X)\n", - rts->ptype, PTYPE_RTS); - return -1; - } - } - - return status; -} - int rts_recv_out_of_sequence_pdu(rdpRpc* rpc) { UINT32 SignatureId; rpcconn_rts_hdr_t* rts; RtsPduSignature signature; - rts = (rpcconn_rts_hdr_t*) rpc->buffer; + rts = (rpcconn_rts_hdr_t*) rpc->FragBuffer; rts_extract_pdu_signature(rpc, &signature, rts); rts_print_pdu_signature(rpc, &signature); @@ -988,11 +966,11 @@ int rts_recv_out_of_sequence_pdu(rdpRpc* rpc) if (SignatureId == RTS_PDU_FLOW_CONTROL_ACK) { - return rts_recv_flow_control_ack_pdu(rpc, rpc->buffer, rpc->length); + return rts_recv_flow_control_ack_pdu(rpc, rpc->FragBuffer, rpc->FragBufferSize); } else if (SignatureId == RTS_PDU_FLOW_CONTROL_ACK_WITH_DESTINATION) { - return rts_recv_flow_control_ack_with_destination_pdu(rpc, rpc->buffer, rpc->length); + return rts_recv_flow_control_ack_with_destination_pdu(rpc, rpc->FragBuffer, rpc->FragBufferSize); } return 0; diff --git a/libfreerdp/core/gateway/rts.h b/libfreerdp/core/gateway/rts.h index 197473e0c..2b4ffc717 100644 --- a/libfreerdp/core/gateway/rts.h +++ b/libfreerdp/core/gateway/rts.h @@ -139,7 +139,6 @@ int rts_send_keep_alive_pdu(rdpRpc* rpc); int rts_send_flow_control_ack_pdu(rdpRpc* rpc); int rts_send_ping_pdu(rdpRpc* rpc); -int rts_recv_pdu(rdpRpc* rpc); int rts_recv_out_of_sequence_pdu(rdpRpc* rpc); #include "rts_signature.h" diff --git a/libfreerdp/core/gateway/tsg.c b/libfreerdp/core/gateway/tsg.c index cdacb844a..91a1f9a8d 100644 --- a/libfreerdp/core/gateway/tsg.c +++ b/libfreerdp/core/gateway/tsg.c @@ -121,13 +121,13 @@ DWORD TsProxySendToServer(handle_t IDL_handle, byte pRpcMessage[], UINT32 count, stream_seal(s); length = s->size; - status = rpc_tsg_write(tsg->rpc, s->data, s->size, TsProxySendToServerOpnum); + status = rpc_write(tsg->rpc, s->data, s->size, TsProxySendToServerOpnum); stream_free(s); if (status <= 0) { - printf("rpc_tsg_write failed!\n"); + printf("rpc_write failed!\n"); return -1; } @@ -186,7 +186,7 @@ BOOL TsProxyCreateTunnelWriteRequest(rdpTsg* tsg) CopyMemory(&buffer[48], TsProxyCreateTunnelUnknownTrailerBytes, 60); - status = rpc_tsg_write(rpc, buffer, length, TsProxyCreateTunnelOpnum); + status = rpc_write(rpc, buffer, length, TsProxyCreateTunnelOpnum); if (status <= 0) return FALSE; @@ -537,7 +537,7 @@ BOOL TsProxyAuthorizeTunnelWriteRequest(rdpTsg* tsg) *((UINT32*) &buffer[offset]) = 0x00000000; /* MaxCount */ offset += 4; - status = rpc_tsg_write(rpc, buffer, length, TsProxyAuthorizeTunnelOpnum); + status = rpc_write(rpc, buffer, length, TsProxyAuthorizeTunnelOpnum); if (status <= 0) return FALSE; @@ -566,7 +566,7 @@ BOOL TsProxyAuthorizeTunnelReadResponse(rdpTsg* tsg) return FALSE; length = status; - buffer = rpc->buffer; + buffer = rpc->FragBuffer; packet = (PTSG_PACKET) malloc(sizeof(TSG_PACKET)); ZeroMemory(packet, sizeof(TSG_PACKET)); @@ -684,7 +684,7 @@ BOOL TsProxyMakeTunnelCallWriteRequest(rdpTsg* tsg) *((UINT32*) &buffer[36]) = 0x00000001; /* MaxMessagesPerBatch */ - status = rpc_tsg_write(rpc, buffer, length, TsProxyMakeTunnelCallOpnum); + status = rpc_write(rpc, buffer, length, TsProxyMakeTunnelCallOpnum); if (status <= 0) return FALSE; @@ -775,7 +775,7 @@ BOOL TsProxyCreateChannelWriteRequest(rdpTsg* tsg) *((UINT32*) &buffer[56]) = count; /* ActualCount */ CopyMemory(&buffer[60], tsg->Hostname, count * 2); /* Array */ - status = rpc_tsg_write(rpc, buffer, length, TsProxyCreateChannelOpnum); + status = rpc_write(rpc, buffer, length, TsProxyCreateChannelOpnum); if (status <= 0) return FALSE; @@ -798,11 +798,11 @@ BOOL TsProxyCreateChannelReadResponse(rdpTsg* tsg) return FALSE; length = status; - buffer = rpc->buffer; + buffer = rpc->FragBuffer; /* ChannelContext (20 bytes) */ - CopyMemory(&tsg->ChannelContext.ContextType, &rpc->buffer[24], 4); /* ContextType (4 bytes) */ - CopyMemory(tsg->ChannelContext.ContextUuid, &rpc->buffer[28], 16); /* ContextUuid (16 bytes) */ + CopyMemory(&tsg->ChannelContext.ContextType, &rpc->FragBuffer[24], 4); /* ContextType (4 bytes) */ + CopyMemory(tsg->ChannelContext.ContextUuid, &rpc->FragBuffer[28], 16); /* ContextUuid (16 bytes) */ /* TODO: trailing bytes */ @@ -871,7 +871,7 @@ BOOL TsProxySetupReceivePipeWriteRequest(rdpTsg* tsg) CopyMemory(&buffer[0], &tsg->ChannelContext.ContextType, 4); /* ContextType */ CopyMemory(&buffer[4], tsg->ChannelContext.ContextUuid, 16); /* ContextUuid */ - status = rpc_tsg_write(rpc, buffer, length, TsProxySetupReceivePipeOpnum); + status = rpc_write(rpc, buffer, length, TsProxySetupReceivePipeOpnum); if (status <= 0) return FALSE; @@ -885,7 +885,7 @@ BOOL TsProxySetupReceivePipeReadResponse(rdpTsg* tsg) { #if 0 int status; - BYTE* buffer; + BYTE* FragBuffer; UINT32 length; rdpRpc* rpc = tsg->rpc; @@ -895,7 +895,7 @@ BOOL TsProxySetupReceivePipeReadResponse(rdpTsg* tsg) return FALSE; length = status; - buffer = rpc->buffer; + FragBuffer = rpc->FragBuffer; #endif return TRUE; @@ -951,6 +951,8 @@ BOOL tsg_connect(rdpTsg* tsg, const char* hostname, UINT16 port) tsg->state = TSG_STATE_INITIAL; + rpc->client->SynchronousSend = TRUE; + /* * Sequential processing rules for connection process: * @@ -1091,6 +1093,8 @@ BOOL tsg_connect(rdpTsg* tsg, const char* hostname, UINT16 port) tsg->state = TSG_STATE_PIPE_CREATED; + rpc->client->SynchronousSend = TRUE; + return TRUE; }