libfreerdp-core: Make tsg out channel recycling event driven
This commit is contained in:
parent
65b2842792
commit
baab23fd14
@ -631,7 +631,6 @@ void* wf_input_thread(void* arg)
|
||||
DWORD WINAPI wf_client_thread(LPVOID lpParam)
|
||||
{
|
||||
MSG msg;
|
||||
int index;
|
||||
int width;
|
||||
int height;
|
||||
BOOL msg_ret;
|
||||
@ -741,8 +740,6 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam)
|
||||
|
||||
if (quit_msg)
|
||||
break;
|
||||
|
||||
Sleep(100);
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
|
@ -890,34 +890,6 @@ int rpc_out_channel_replacement_connect(RpcOutChannel* outChannel, int timeout)
|
||||
|
||||
rpc_out_channel_transition_to_state(outChannel, CLIENT_OUT_CHANNEL_STATE_SECURITY);
|
||||
|
||||
/* Receive response. */
|
||||
response = http_response_recv(outChannel->tls);
|
||||
|
||||
if (!response)
|
||||
return -1;
|
||||
|
||||
status = rpc_ncacn_http_recv_out_channel_response(rpc, outChannel, response);
|
||||
|
||||
http_response_free(response);
|
||||
|
||||
if ( status < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "rpc_ncacn_http_recv_out_channel_response failure");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Send OUT Channel Request */
|
||||
|
||||
if (rpc_ncacn_http_send_out_channel_request(rpc, outChannel, TRUE) < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "rpc_ncacn_http_send_out_channel_request failure");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rpc_ncacn_http_ntlm_uninit(rpc, (RpcChannel*) outChannel);
|
||||
|
||||
rpc_out_channel_transition_to_state(outChannel, CLIENT_OUT_CHANNEL_STATE_NEGOTIATED);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -654,6 +654,7 @@ enum _CLIENT_OUT_CHANNEL_STATE
|
||||
CLIENT_OUT_CHANNEL_STATE_OPENED_A6W,
|
||||
CLIENT_OUT_CHANNEL_STATE_OPENED_A10W,
|
||||
CLIENT_OUT_CHANNEL_STATE_OPENED_B3W,
|
||||
CLIENT_OUT_CHANNEL_STATE_RECYCLED,
|
||||
CLIENT_OUT_CHANNEL_STATE_FINAL
|
||||
};
|
||||
typedef enum _CLIENT_OUT_CHANNEL_STATE CLIENT_OUT_CHANNEL_STATE;
|
||||
|
@ -445,7 +445,7 @@ int rpc_client_recv_fragment(rdpRpc* rpc, wStream* fragment)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int rpc_client_out_channel_recv(rdpRpc* rpc)
|
||||
int rpc_client_default_out_channel_recv(rdpRpc* rpc)
|
||||
{
|
||||
int status = -1;
|
||||
HttpResponse* response;
|
||||
@ -481,10 +481,10 @@ int rpc_client_out_channel_recv(rdpRpc* rpc)
|
||||
return -1;
|
||||
}
|
||||
|
||||
rpc_ncacn_http_ntlm_uninit(rpc, (RpcChannel*) outChannel);
|
||||
rpc_ncacn_http_ntlm_uninit(rpc, (RpcChannel*)outChannel);
|
||||
|
||||
rpc_out_channel_transition_to_state(outChannel,
|
||||
CLIENT_OUT_CHANNEL_STATE_NEGOTIATED);
|
||||
CLIENT_OUT_CHANNEL_STATE_NEGOTIATED);
|
||||
|
||||
/* Send CONN/A1 PDU over OUT channel */
|
||||
|
||||
@ -495,7 +495,7 @@ int rpc_client_out_channel_recv(rdpRpc* rpc)
|
||||
}
|
||||
|
||||
rpc_out_channel_transition_to_state(outChannel,
|
||||
CLIENT_OUT_CHANNEL_STATE_OPENED);
|
||||
CLIENT_OUT_CHANNEL_STATE_OPENED);
|
||||
|
||||
if (inChannel->State == CLIENT_IN_CHANNEL_STATE_OPENED)
|
||||
{
|
||||
@ -535,7 +535,7 @@ int rpc_client_out_channel_recv(rdpRpc* rpc)
|
||||
http_response_free(response);
|
||||
|
||||
rpc_virtual_connection_transition_to_state(rpc,
|
||||
rpc->VirtualConnection, VIRTUAL_CONNECTION_STATE_WAIT_A3W);
|
||||
rpc->VirtualConnection, VIRTUAL_CONNECTION_STATE_WAIT_A3W);
|
||||
|
||||
status = 1;
|
||||
}
|
||||
@ -551,7 +551,7 @@ int rpc_client_out_channel_recv(rdpRpc* rpc)
|
||||
while (Stream_GetPosition(fragment) < RPC_COMMON_FIELDS_LENGTH)
|
||||
{
|
||||
status = rpc_out_channel_read(outChannel, Stream_Pointer(fragment),
|
||||
RPC_COMMON_FIELDS_LENGTH - Stream_GetPosition(fragment));
|
||||
RPC_COMMON_FIELDS_LENGTH - Stream_GetPosition(fragment));
|
||||
|
||||
if (status < 0)
|
||||
return -1;
|
||||
@ -565,12 +565,12 @@ int rpc_client_out_channel_recv(rdpRpc* rpc)
|
||||
if (Stream_GetPosition(fragment) < RPC_COMMON_FIELDS_LENGTH)
|
||||
return status;
|
||||
|
||||
header = (rpcconn_common_hdr_t*) Stream_Buffer(fragment);
|
||||
header = (rpcconn_common_hdr_t*)Stream_Buffer(fragment);
|
||||
|
||||
if (header->frag_length > rpc->max_recv_frag)
|
||||
{
|
||||
WLog_ERR(TAG, "rpc_client_recv: invalid fragment size: %d (max: %d)",
|
||||
header->frag_length, rpc->max_recv_frag);
|
||||
header->frag_length, rpc->max_recv_frag);
|
||||
winpr_HexDump(TAG, WLOG_ERROR, Stream_Buffer(fragment), Stream_GetPosition(fragment));
|
||||
return -1;
|
||||
}
|
||||
@ -578,7 +578,7 @@ int rpc_client_out_channel_recv(rdpRpc* rpc)
|
||||
while (Stream_GetPosition(fragment) < header->frag_length)
|
||||
{
|
||||
status = rpc_out_channel_read(outChannel, Stream_Pointer(fragment),
|
||||
header->frag_length - Stream_GetPosition(fragment));
|
||||
header->frag_length - Stream_GetPosition(fragment));
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
@ -604,13 +604,23 @@ int rpc_client_out_channel_recv(rdpRpc* rpc)
|
||||
|
||||
status = rpc_client_recv_fragment(rpc, fragment);
|
||||
|
||||
/* channel recycling may update channel pointers */
|
||||
inChannel = connection->DefaultInChannel;
|
||||
outChannel = connection->DefaultOutChannel;
|
||||
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
/* channel recycling may update channel pointers */
|
||||
inChannel = connection->DefaultInChannel;
|
||||
if (outChannel->State == CLIENT_OUT_CHANNEL_STATE_RECYCLED && connection->NonDefaultOutChannel)
|
||||
{
|
||||
rpc_out_channel_free(connection->DefaultOutChannel);
|
||||
connection->DefaultOutChannel = connection->NonDefaultOutChannel;
|
||||
connection->NonDefaultOutChannel = NULL;
|
||||
|
||||
rpc_out_channel_transition_to_state(connection->DefaultOutChannel, CLIENT_OUT_CHANNEL_STATE_OPENED);
|
||||
rpc_virtual_connection_transition_to_state(rpc, connection, VIRTUAL_CONNECTION_STATE_OUT_CHANNEL_WAIT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Stream_SetPosition(fragment, 0);
|
||||
}
|
||||
}
|
||||
@ -619,6 +629,83 @@ int rpc_client_out_channel_recv(rdpRpc* rpc)
|
||||
return status;
|
||||
}
|
||||
|
||||
int rpc_client_nondefault_out_channel_recv(rdpRpc* rpc)
|
||||
{
|
||||
int status = -1;
|
||||
HttpResponse* response;
|
||||
RpcOutChannel* nextOutChannel;
|
||||
|
||||
nextOutChannel = rpc->VirtualConnection->NonDefaultOutChannel;
|
||||
|
||||
response = http_response_recv(nextOutChannel->tls);
|
||||
if (response)
|
||||
{
|
||||
if (nextOutChannel->State == CLIENT_OUT_CHANNEL_STATE_SECURITY)
|
||||
{
|
||||
status = rpc_ncacn_http_recv_out_channel_response(rpc, nextOutChannel, response);
|
||||
if (status >= 0)
|
||||
{
|
||||
status = rpc_ncacn_http_send_out_channel_request(rpc, nextOutChannel, TRUE);
|
||||
if (status >= 0)
|
||||
{
|
||||
rpc_ncacn_http_ntlm_uninit(rpc, (RpcChannel*)nextOutChannel);
|
||||
status = rts_send_OUT_R1_A3_pdu(rpc);
|
||||
if (status >= 0)
|
||||
{
|
||||
rpc_out_channel_transition_to_state(nextOutChannel, CLIENT_OUT_CHANNEL_STATE_OPENED_A6W);
|
||||
}
|
||||
else
|
||||
{
|
||||
WLog_ERR(TAG, "rts_send_OUT_R1/A3_pdu failure");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WLog_ERR(TAG, "rpc_ncacn_http_send_out_channel_request failure");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WLog_ERR(TAG, "rpc_ncacn_http_recv_out_channel_response failure");
|
||||
}
|
||||
}
|
||||
|
||||
http_response_free(response);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int rpc_client_out_channel_recv(rdpRpc* rpc)
|
||||
{
|
||||
RpcOutChannel* outChannel;
|
||||
RpcOutChannel* nextOutChannel;
|
||||
RpcVirtualConnection* connection = rpc->VirtualConnection;
|
||||
HANDLE outChannelEvent = NULL;
|
||||
HANDLE nextOutChannelEvent = NULL;
|
||||
|
||||
outChannel = connection->DefaultOutChannel;
|
||||
BIO_get_event(outChannel->tls->bio, &outChannelEvent);
|
||||
|
||||
if (WaitForSingleObject(outChannelEvent, 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
return rpc_client_default_out_channel_recv(rpc);
|
||||
}
|
||||
|
||||
nextOutChannel = connection->NonDefaultOutChannel;
|
||||
if (nextOutChannel)
|
||||
{
|
||||
BIO_get_event(nextOutChannel->tls->bio, &nextOutChannelEvent);
|
||||
|
||||
if (WaitForSingleObject(nextOutChannelEvent, 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
return rpc_client_nondefault_out_channel_recv(rpc);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rpc_client_in_channel_recv(rdpRpc* rpc)
|
||||
{
|
||||
int status = -1;
|
||||
|
@ -926,15 +926,6 @@ int rts_recv_OUT_R1_A2_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = rts_send_OUT_R1_A3_pdu(rpc);
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "rts_send_OUT_R1/A3_pdu failure");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rpc_out_channel_transition_to_state(connection->NonDefaultOutChannel, CLIENT_OUT_CHANNEL_STATE_OPENED_A6W);
|
||||
rpc_out_channel_transition_to_state(connection->DefaultOutChannel, CLIENT_OUT_CHANNEL_STATE_OPENED_A6W);
|
||||
|
||||
return 1;
|
||||
@ -971,26 +962,11 @@ int rts_recv_OUT_R2_A6_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
||||
|
||||
int rts_recv_OUT_R2_B3_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
||||
{
|
||||
int status;
|
||||
HttpResponse* response;
|
||||
RpcVirtualConnection* connection = rpc->VirtualConnection;
|
||||
|
||||
WLog_DBG(TAG, "Receiving OUT R2/B3 RTS PDU");
|
||||
|
||||
rpc_out_channel_free(connection->DefaultOutChannel);
|
||||
connection->DefaultOutChannel = connection->NonDefaultOutChannel;
|
||||
connection->NonDefaultOutChannel = NULL;
|
||||
|
||||
rpc_out_channel_transition_to_state(connection->DefaultOutChannel, CLIENT_OUT_CHANNEL_STATE_OPENED);
|
||||
|
||||
response = http_response_recv(connection->DefaultOutChannel->tls);
|
||||
|
||||
if (!response)
|
||||
return -1;
|
||||
|
||||
status = rpc_ncacn_http_recv_out_channel_response(rpc, connection->DefaultOutChannel, response);
|
||||
|
||||
http_response_free(response);
|
||||
rpc_out_channel_transition_to_state(connection->DefaultOutChannel, CLIENT_OUT_CHANNEL_STATE_RECYCLED);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -135,6 +135,8 @@ int rts_send_CONN_B1_pdu(rdpRpc* rpc);
|
||||
|
||||
int rts_recv_CONN_C2_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length);
|
||||
|
||||
int rts_send_OUT_R1_A3_pdu(rdpRpc* rpc);
|
||||
|
||||
int rts_send_keep_alive_pdu(rdpRpc* rpc);
|
||||
int rts_send_flow_control_ack_pdu(rdpRpc* rpc);
|
||||
int rts_send_ping_pdu(rdpRpc* rpc);
|
||||
|
Loading…
Reference in New Issue
Block a user