void* wfds[32];
fd_set rfds_set;
fd_set wfds_set;
+ struct timeval timeout;
+ int select_status;
memset(rfds, 0, sizeof(rfds));
memset(wfds, 0, sizeof(wfds));
- while (1)
+ while (!freerdp_shall_disconnect(instance))
{
rcount = wcount = 0;
FD_SET(fds, &rfds_set);
}
-
+
if (max_fds == 0)
break;
-
- if (select(max_fds + 1, &rfds_set, &wfds_set, NULL, NULL) == -1)
+
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+
+ select_status = select(max_fds + 1, &rfds_set, NULL, NULL, &timeout);
+
+ // timeout?
+ if (select_status == 0)
+ continue;
+ else if (select_status == -1)
{
/* these are not really errors */
if (!((errno == EAGAIN) ||
(errno == EINPROGRESS) ||
(errno == EINTR))) /* signal occurred */
{
- NSLog(@"%s: max_sck is zero.", __func__);
+ NSLog(@"%s: select failed!", __func__);
break;
}
}
#include "rpc_client.h"
+#include "../rdp.h"
+
wStream* rpc_client_fragment_pool_take(rdpRpc* rpc)
{
wStream* fragment = NULL;
if (StubLength == 4)
{
//fprintf(stderr, "Ignoring TsProxySendToServer Response\n");
+ printf("Got stub length 4 with flags %d and callid %d\n", header->common.pfc_flags, header->common.call_id);
+
+ /* received a disconnect request from the server? */
+ if (header->common.call_id == rpc->PipeCallId && header->common.pfc_flags & PFC_LAST_FRAG)
+ {
+ ((freerdp*)rpc->settings->instance)->context->rdp->disconnect = TRUE;
+ ((freerdp*)rpc->settings->instance)->context->rdp->transport->tsg->state = TSG_STATE_TUNNEL_CLOSE_PENDING;
+ }
+
rpc_client_fragment_pool_return(rpc, fragment);
return 0;
}
tsg->rpc->client->SynchronousReceive = TRUE;
- if (!TsProxyCloseChannel(tsg, NULL))
- return FALSE;
+ /* if we are already in state pending (i.e. if a server initiated disconnect was issued)
+ we have to skip TsProxyCloseChannel - see Figure 13 in section 3.2.3
+ */
+ if (tsg->state != TSG_STATE_TUNNEL_CLOSE_PENDING)
+ {
+ if (!TsProxyCloseChannel(tsg, NULL))
+ return FALSE;
+ }
if (!TsProxyMakeTunnelCall(tsg, &tsg->TunnelContext, TSG_TUNNEL_CANCEL_ASYNC_MSG_REQUEST, NULL, NULL))
return FALSE;