static void* rpc_client_thread(void* arg)
{
- int fd;
DWORD status;
DWORD nCount;
HANDLE events[3];
HANDLE ReadEvent;
rdpRpc* rpc = (rdpRpc*) arg;
- fd = BIO_get_fd(rpc->TlsOut->bio, NULL);
- ReadEvent = CreateFileDescriptorEvent(NULL, TRUE, FALSE, fd);
+ if (!BIO_get_event(rpc->TlsOut->bio, &ReadEvent))
+ {
+ WLog_ERR(TAG, "rpc_client_thread: failed to obtain read event from underlying BIO");
+ goto out;
+ }
nCount = 0;
events[nCount++] = rpc->client->StopEvent;
events[nCount++] = Queue_Event(rpc->client->SendQueue);
events[nCount++] = ReadEvent;
- /* Do a first free run in case some bytes were set from the HTTP headers.
- * We also have to do it because most of the time the underlying socket has notified,
- * and the ssl layer has eaten all bytes, so we won't be notified any more even if the
- * bytes are buffered locally
- */
- if (rpc_client_on_read_event(rpc) < 0)
- {
- WLog_ERR(TAG, "an error occurred when treating first packet");
- goto out;
- }
-
while (rpc->transport->layer != TRANSPORT_LAYER_CLOSED)
{
status = WaitForMultipleObjects(nCount, events, FALSE, 100);
}
out:
- CloseHandle(ReadEvent);
return NULL;
}
{
int status = -1;
+ if (cmd == BIO_C_GET_EVENT)
+ {
+ if (!bio->init || !arg2)
+ return 0;
+
+#ifndef _WIN32
+ if (!bio->ptr)
+ bio->ptr = CreateFileDescriptorEvent(NULL, FALSE, FALSE, bio->num);
+#else
+ if (!bio->ptr)
+ bio->ptr = (void*) WSACreateEvent();
+
+ WSAEventSelect(bio->num, (HANDLE) bio->ptr, FD_READ);
+#endif
+
+ *((ULONG_PTR*) arg2) = (ULONG_PTR) bio->ptr;
+
+ return 1;
+ }
+ else if (cmd == BIO_C_SET_NONBLOCK)
+ {
+#ifndef _WIN32
+ int flags;
+
+ flags = fcntl(bio->num, F_GETFL);
+
+ if (flags == -1)
+ return 0;
+
+ if (arg1)
+ fcntl(bio->num, F_SETFL, flags | O_NONBLOCK);
+ else
+ fcntl(bio->num, F_SETFL, flags & ~(O_NONBLOCK));
+#else
+ if (arg1)
+ {
+ if (!bio->ptr)
+ bio->ptr = (void*) WSACreateEvent();
+
+ WSAEventSelect(bio->num, (HANDLE) bio->ptr, FD_READ);
+ }
+ else
+ {
+ if (bio->ptr)
+ WSAEventSelect(bio->num, (HANDLE) bio->ptr, 0);
+ }
+#endif
+ return 1;
+ }
+
switch (cmd)
{
case BIO_C_SET_FD:
bio->num = 0;
bio->ptr = NULL;
bio->flags = BIO_FLAGS_SHOULD_RETRY;
+
return 1;
}
if (bio->shutdown)
{
if (bio->init)
+ {
+ if (bio->ptr)
+ {
+ CloseHandle((HANDLE) bio->ptr);
+ bio->ptr = NULL;
+ }
+
closesocket((SOCKET) bio->num);
+ }
bio->init = 0;
bio->flags = 0;
BIO_set_fd(tcp->socketBio, tcp->sockfd, BIO_CLOSE);
}
- SetEventFileDescriptor(tcp->event, tcp->sockfd);
+ BIO_get_event(tcp->socketBio, &tcp->event);
freerdp_tcp_get_ip_address(tcp);
freerdp_tcp_get_mac_address(tcp);
BOOL freerdp_tcp_set_blocking_mode(rdpTcp* tcp, BOOL blocking)
{
-#ifndef _WIN32
- int flags;
- flags = fcntl(tcp->sockfd, F_GETFL);
-
- if (flags == -1)
- {
- WLog_ERR(TAG, "fcntl failed, %s.", strerror(errno));
- return FALSE;
- }
-
- if (blocking == TRUE)
- fcntl(tcp->sockfd, F_SETFL, flags & ~(O_NONBLOCK));
- else
- fcntl(tcp->sockfd, F_SETFL, flags | O_NONBLOCK);
-#else
- /**
- * ioctlsocket function:
- * msdn.microsoft.com/en-ca/library/windows/desktop/ms738573/
- *
- * The WSAAsyncSelect and WSAEventSelect functions automatically set a socket to nonblocking mode.
- * If WSAAsyncSelect or WSAEventSelect has been issued on a socket, then any attempt to use
- * ioctlsocket to set the socket back to blocking mode will fail with WSAEINVAL.
- *
- * To set the socket back to blocking mode, an application must first disable WSAAsyncSelect
- * by calling WSAAsyncSelect with the lEvent parameter equal to zero, or disable WSAEventSelect
- * by calling WSAEventSelect with the lNetworkEvents parameter equal to zero.
- */
-
- if (blocking == TRUE)
- {
- if (tcp->event)
- WSAEventSelect(tcp->sockfd, tcp->event, 0);
- }
- else
- {
- if (!tcp->event)
- tcp->event = WSACreateEvent();
-
- WSAEventSelect(tcp->sockfd, tcp->event, FD_READ);
- }
-#endif
-
- return TRUE;
+ return BIO_set_nonblock(tcp->socketBio, blocking ? 0 : 1) ? TRUE : FALSE;
}
BOOL freerdp_tcp_set_keep_alive_mode(rdpTcp* tcp)
int freerdp_tcp_attach(rdpTcp* tcp, int sockfd)
{
tcp->sockfd = sockfd;
- SetEventFileDescriptor(tcp->event, tcp->sockfd);
ringbuffer_commit_read_bytes(&tcp->xmitBuffer, ringbuffer_used(&tcp->xmitBuffer));
tcp->bufferedBio = BIO_push(tcp->bufferedBio, tcp->socketBio);
}
- return 0;
+ BIO_get_event(tcp->socketBio, &tcp->event);
+
+ return 1;
}
HANDLE freerdp_tcp_get_event_handle(rdpTcp* tcp)
tcp->sockfd = -1;
tcp->settings = settings;
- if (0)
- goto out_ringbuffer; /* avoid unreferenced label warning on Windows */
-
-#ifndef _WIN32
- tcp->event = CreateFileDescriptorEvent(NULL, FALSE, FALSE, tcp->sockfd);
-
- if (!tcp->event || tcp->event == INVALID_HANDLE_VALUE)
- goto out_ringbuffer;
-#endif
-
return tcp;
-out_ringbuffer:
- ringbuffer_destroy(&tcp->xmitBuffer);
+
out_free:
free(tcp);
return NULL;
return;
ringbuffer_destroy(&tcp->xmitBuffer);
- CloseHandle(tcp->event);
+
+ if (tcp->socketBio)
+ {
+ BIO_free(tcp->socketBio);
+ tcp->socketBio = NULL;
+ }
+
+ if (tcp->bufferedBio)
+ {
+ BIO_free(tcp->bufferedBio);
+ tcp->bufferedBio = NULL;
+ }
+
free(tcp);
}