libfreerdp-core: started handling flow control, can get further with TSG
This commit is contained in:
parent
25efc0da84
commit
0073d0baea
@ -458,7 +458,10 @@ int rpc_in_write(rdpRpc* rpc, BYTE* data, int length)
|
||||
status = tls_write_all(rpc->TlsIn, data, length);
|
||||
|
||||
if (status > 0)
|
||||
{
|
||||
rpc->VirtualConnection->DefaultInChannel->BytesSent += status;
|
||||
rpc->VirtualConnection->DefaultInChannel->SenderAvailableWindow -= status;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
@ -812,18 +815,31 @@ int rpc_recv_pdu(rdpRpc* rpc)
|
||||
|
||||
if (header->common.ptype == PTYPE_RTS) /* RTS PDU */
|
||||
{
|
||||
return header->common.frag_length;
|
||||
if (rpc->VirtualConnection->State < VIRTUAL_CONNECTION_STATE_OPENED)
|
||||
return header->common.frag_length;
|
||||
|
||||
printf("Receiving Out-of-Sequence RTS PDU\n");
|
||||
rts_recv_out_of_sequence_pdu(rpc);
|
||||
return rpc_recv_pdu(rpc);
|
||||
}
|
||||
else if (header->common.ptype == PTYPE_FAULT)
|
||||
{
|
||||
rpc_recv_fault_pdu(header);
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
|
||||
rpc->VirtualConnection->DefaultOutChannel->BytesReceived += header->common.frag_length;
|
||||
rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow -= header->common.frag_length;
|
||||
|
||||
/*printf("BytesReceived: %d ReceiverAvailableWindow: %d ReceiveWindow: %d\n",
|
||||
rpc->VirtualConnection->DefaultOutChannel->BytesReceived,
|
||||
rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow,
|
||||
rpc->ReceiveWindow);*/
|
||||
|
||||
if (rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow < (rpc->ReceiveWindow / 2))
|
||||
{
|
||||
/* RTS PDUs are not subject to flow control */
|
||||
rpc->VirtualConnection->DefaultOutChannel->BytesReceived += header->common.frag_length;
|
||||
rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow -= header->common.frag_length;
|
||||
printf("Sending Flow Control Ack PDU\n");
|
||||
rts_send_flow_control_ack_pdu(rpc);
|
||||
}
|
||||
|
||||
#ifdef WITH_DEBUG_RPC
|
||||
@ -986,6 +1002,7 @@ void rpc_client_virtual_connection_init(rdpRpc* rpc, RpcVirtualConnection* conne
|
||||
connection->DefaultOutChannel->ReceiverAvailableWindow = rpc->ReceiveWindow;
|
||||
connection->DefaultOutChannel->ReceiveWindow = rpc->ReceiveWindow;
|
||||
connection->DefaultOutChannel->ReceiveWindowSize = rpc->ReceiveWindow;
|
||||
connection->DefaultOutChannel->AvailableWindowAdvertised = rpc->ReceiveWindow;
|
||||
}
|
||||
|
||||
RpcVirtualConnection* rpc_client_virtual_connection_new(rdpRpc* rpc)
|
||||
|
@ -840,9 +840,12 @@ int rts_send_flow_control_ack_pdu(rdpRpc* rpc)
|
||||
DEBUG_RPC("Sending FlowControlAck RTS PDU");
|
||||
|
||||
BytesReceived = rpc->VirtualConnection->DefaultOutChannel->BytesReceived;
|
||||
AvailableWindow = rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow;
|
||||
AvailableWindow = rpc->VirtualConnection->DefaultOutChannel->AvailableWindowAdvertised;
|
||||
ChannelCookie = (BYTE*) &(rpc->VirtualConnection->DefaultOutChannelCookie);
|
||||
|
||||
rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow =
|
||||
rpc->VirtualConnection->DefaultOutChannel->AvailableWindowAdvertised;
|
||||
|
||||
buffer = (BYTE*) malloc(header.frag_length);
|
||||
|
||||
CopyMemory(buffer, ((BYTE*) &header), 20); /* RTS Header (20 bytes) */
|
||||
@ -1192,6 +1195,74 @@ BOOL rts_match_pdu_signature(rdpRpc* rpc, RtsPduSignature* signature, rpcconn_rt
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int rts_extract_pdu_signature(rdpRpc* rpc, RtsPduSignature* signature, rpcconn_rts_hdr_t* rts)
|
||||
{
|
||||
int i;
|
||||
int status;
|
||||
BYTE* buffer;
|
||||
UINT32 length;
|
||||
UINT32 offset;
|
||||
UINT32 CommandType;
|
||||
UINT32 CommandLength;
|
||||
|
||||
signature->Flags = rts->Flags;
|
||||
signature->NumberOfCommands = rts->NumberOfCommands;
|
||||
|
||||
buffer = (BYTE*) rts;
|
||||
offset = RTS_PDU_HEADER_LENGTH;
|
||||
length = rts->frag_length - offset;
|
||||
|
||||
for (i = 0; i < rts->NumberOfCommands; i++)
|
||||
{
|
||||
CommandType = *((UINT32*) &buffer[offset]); /* CommandType (4 bytes) */
|
||||
offset += 4;
|
||||
|
||||
signature->CommandTypes[i] = CommandType;
|
||||
|
||||
status = rts_command_length(rpc, CommandType, &buffer[offset], length);
|
||||
|
||||
if (status < 0)
|
||||
return FALSE;
|
||||
|
||||
CommandLength = (UINT32) status;
|
||||
offset += CommandLength;
|
||||
|
||||
length = rts->frag_length - offset;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rts_print_pdu_signature(rdpRpc* rpc, RtsPduSignature* signature)
|
||||
{
|
||||
int i, j;
|
||||
RtsPduSignature* pSignature;
|
||||
|
||||
printf("RTS PDU Signature: Flags: 0x%04X NumberOfCommands: %d\n",
|
||||
signature->Flags, signature->NumberOfCommands);
|
||||
|
||||
for (i = 0; RTS_PDU_SIGNATURE_TABLE[i].SignatureId != 0; i++)
|
||||
{
|
||||
pSignature = RTS_PDU_SIGNATURE_TABLE[i].Signature;
|
||||
|
||||
if (signature->Flags == pSignature->Flags)
|
||||
{
|
||||
if (signature->NumberOfCommands == pSignature->NumberOfCommands)
|
||||
{
|
||||
for (j = 0; j < signature->NumberOfCommands; j++)
|
||||
{
|
||||
if (signature->CommandTypes[j] != pSignature->CommandTypes[j])
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("Identified %s RTS PDU\n", RTS_PDU_SIGNATURE_TABLE[i].PduName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rts_recv_pdu_commands(rdpRpc* rpc, rpcconn_rts_hdr_t* rts)
|
||||
{
|
||||
int i;
|
||||
@ -1317,3 +1388,16 @@ int rts_recv_pdu(rdpRpc* rpc)
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int rts_recv_out_of_sequence_pdu(rdpRpc* rpc)
|
||||
{
|
||||
rpcconn_rts_hdr_t* rts;
|
||||
RtsPduSignature signature;
|
||||
|
||||
rts = (rpcconn_rts_hdr_t*) rpc->buffer;
|
||||
|
||||
rts_extract_pdu_signature(rpc, &signature, rts);
|
||||
rts_print_pdu_signature(rpc, &signature);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -222,6 +222,7 @@ 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);
|
||||
|
||||
#ifdef WITH_DEBUG_TSG
|
||||
#define WITH_DEBUG_RTS
|
||||
|
Loading…
Reference in New Issue
Block a user