libfreerdp-core: fix random TS Gateway disconnects with async modes

This commit is contained in:
Marc-André Moreau 2014-12-12 09:08:39 -05:00
parent cc2321d359
commit aa23c4eaaa
3 changed files with 153 additions and 11 deletions

View File

@ -131,7 +131,7 @@ int rpc_client_on_fragment_received_event(rdpRpc* rpc)
return 0; return 0;
} }
WLog_ERR(TAG, "Receiving Out-of-Sequence RTS PDU"); WLog_DBG(TAG, "Receiving Out-of-Sequence RTS PDU");
rts_recv_out_of_sequence_pdu(rpc, buffer, header->common.frag_length); rts_recv_out_of_sequence_pdu(rpc, buffer, header->common.frag_length);
rpc_client_fragment_pool_return(rpc, fragment); rpc_client_fragment_pool_return(rpc, fragment);
return 0; return 0;

View File

@ -30,6 +30,7 @@
#include <winpr/synch.h> #include <winpr/synch.h>
#include <winpr/print.h> #include <winpr/print.h>
#include <winpr/stream.h> #include <winpr/stream.h>
#include <winpr/winsock.h>
#include <freerdp/log.h> #include <freerdp/log.h>
#include <freerdp/error.h> #include <freerdp/error.h>
@ -120,15 +121,21 @@ long transport_bio_tsg_callback(BIO* bio, int mode, const char* argp, int argi,
static int transport_bio_tsg_write(BIO* bio, const char* buf, int num) static int transport_bio_tsg_write(BIO* bio, const char* buf, int num)
{ {
int status; int status;
rdpTsg* tsg; rdpTsg* tsg = (rdpTsg*) bio->ptr;
tsg = (rdpTsg*) bio->ptr;
BIO_clear_flags(bio, BIO_FLAGS_WRITE); BIO_clear_flags(bio, BIO_FLAGS_WRITE);
status = tsg_write(tsg, (BYTE*) buf, num); status = tsg_write(tsg, (BYTE*) buf, num);
if (status < 0) if (status < 0)
{ {
BIO_clear_flags(bio, BIO_FLAGS_SHOULD_RETRY); BIO_clear_flags(bio, BIO_FLAGS_SHOULD_RETRY);
} }
else if (status == 0)
{
BIO_set_flags(bio, BIO_FLAGS_SHOULD_RETRY);
WSASetLastError(WSAEWOULDBLOCK);
}
else else
{ {
BIO_set_flags(bio, BIO_FLAGS_WRITE); BIO_set_flags(bio, BIO_FLAGS_WRITE);
@ -140,10 +147,11 @@ static int transport_bio_tsg_write(BIO* bio, const char* buf, int num)
static int transport_bio_tsg_read(BIO* bio, char* buf, int size) static int transport_bio_tsg_read(BIO* bio, char* buf, int size)
{ {
int status; int status;
rdpTsg* tsg; rdpTsg* tsg = (rdpTsg*) bio->ptr;
tsg = (rdpTsg*) bio->ptr;
BIO_clear_flags(bio, BIO_FLAGS_READ); BIO_clear_flags(bio, BIO_FLAGS_READ);
status = tsg_read(bio->ptr, (BYTE*) buf, size);
status = tsg_read(tsg, (BYTE*) buf, size);
if (status < 0) if (status < 0)
{ {
@ -152,6 +160,7 @@ static int transport_bio_tsg_read(BIO* bio, char* buf, int size)
else if (status == 0) else if (status == 0)
{ {
BIO_set_flags(bio, BIO_FLAGS_SHOULD_RETRY); BIO_set_flags(bio, BIO_FLAGS_SHOULD_RETRY);
WSASetLastError(WSAEWOULDBLOCK);
} }
else else
{ {

View File

@ -276,7 +276,145 @@ int WSACleanup(void)
void WSASetLastError(int iError) void WSASetLastError(int iError)
{ {
switch (iError)
{
/* Base error codes */
case WSAEINTR:
errno = EINTR;
break;
case WSAEBADF:
errno = EBADF;
break;
case WSAEACCES:
errno = EACCES;
break;
case WSAEFAULT:
errno = EFAULT;
break;
case WSAEINVAL:
errno = EINVAL;
break;
case WSAEMFILE:
errno = EMFILE;
break;
/* BSD sockets error codes */
case WSAEWOULDBLOCK:
errno = EWOULDBLOCK;
break;
case WSAEINPROGRESS:
errno = EINPROGRESS;
break;
case WSAEALREADY:
errno = EALREADY;
break;
case WSAENOTSOCK:
errno = ENOTSOCK;
break;
case WSAEDESTADDRREQ:
errno = EDESTADDRREQ;
break;
case WSAEMSGSIZE:
errno = EMSGSIZE;
break;
case WSAEPROTOTYPE:
errno = EPROTOTYPE;
break;
case WSAENOPROTOOPT:
errno = ENOPROTOOPT;
break;
case WSAEPROTONOSUPPORT:
errno = EPROTONOSUPPORT;
break;
case WSAESOCKTNOSUPPORT:
errno = ESOCKTNOSUPPORT;
break;
case WSAEOPNOTSUPP:
errno = EOPNOTSUPP;
break;
case WSAEPFNOSUPPORT:
errno = EPFNOSUPPORT;
break;
case WSAEAFNOSUPPORT:
errno = EAFNOSUPPORT;
break;
case WSAEADDRINUSE:
errno = EADDRINUSE;
break;
case WSAEADDRNOTAVAIL:
errno = EADDRNOTAVAIL;
break;
case WSAENETDOWN:
errno = ENETDOWN;
break;
case WSAENETUNREACH:
errno = ENETUNREACH;
break;
case WSAENETRESET:
errno = ENETRESET;
break;
case WSAECONNABORTED:
errno = ECONNABORTED;
break;
case WSAECONNRESET:
errno = ECONNRESET;
break;
case WSAENOBUFS:
errno = ENOBUFS;
break;
case WSAEISCONN:
errno = EISCONN;
break;
case WSAENOTCONN:
errno = ENOTCONN;
break;
case WSAESHUTDOWN:
errno = ESHUTDOWN;
break;
case WSAETOOMANYREFS:
errno = ETOOMANYREFS;
break;
case WSAETIMEDOUT:
errno = ETIMEDOUT;
break;
case WSAECONNREFUSED:
errno = ECONNREFUSED;
break;
case WSAELOOP:
errno = ELOOP;
break;
case WSAENAMETOOLONG:
errno = ENAMETOOLONG;
break;
case WSAEHOSTDOWN:
errno = EHOSTDOWN;
break;
case WSAEHOSTUNREACH:
errno = EHOSTUNREACH;
break;
case WSAENOTEMPTY:
errno = ENOTEMPTY;
break;
#ifdef EPROCLIM
case WSAEPROCLIM:
errno = EPROCLIM;
break;
#endif
case WSAEUSERS:
errno = EUSERS;
break;
case WSAEDQUOT:
errno = EDQUOT;
break;
case WSAESTALE:
errno = ESTALE;
break;
case WSAEREMOTE:
errno = EREMOTE;
break;
}
} }
int WSAGetLastError(void) int WSAGetLastError(void)
@ -290,23 +428,18 @@ int WSAGetLastError(void)
case EINTR: case EINTR:
iError = WSAEINTR; iError = WSAEINTR;
break; break;
case EBADF: case EBADF:
iError = WSAEBADF; iError = WSAEBADF;
break; break;
case EACCES: case EACCES:
iError = WSAEACCES; iError = WSAEACCES;
break; break;
case EFAULT: case EFAULT:
iError = WSAEFAULT; iError = WSAEFAULT;
break; break;
case EINVAL: case EINVAL:
iError = WSAEINVAL; iError = WSAEINVAL;
break; break;
case EMFILE: case EMFILE:
iError = WSAEMFILE; iError = WSAEMFILE;
break; break;