int transport_read(rdpTransport* transport, STREAM* s) { int status = -1; while (true) { if (transport->layer == TRANSPORT_LAYER_TLS) status = tls_read(transport->tls, stream_get_tail(s), stream_get_left(s)); else if (transport->layer == TRANSPORT_LAYER_TCP) status = tcp_read(transport->tcp, stream_get_tail(s), stream_get_left(s)); else if (transport->layer == TRANSPORT_LAYER_TSG) status = tsg_read(transport->tsg, stream_get_tail(s), stream_get_left(s)); if (status == 0 && transport->blocking) { freerdp_usleep(transport->usleep_interval); continue; } break; } #ifdef WITH_DEBUG_TRANSPORT if (status > 0) { printf("Local < Remote\n"); freerdp_hexdump(s->data, status); } #endif return status; }
int tsg_read(rdpTsg* tsg, BYTE* data, UINT32 length) { int CopyLength; rdpRpc* rpc; if (tsg == NULL) return -1; rpc = tsg->rpc; if (tsg->PendingPdu) { CopyLength = (length < tsg->BytesAvailable) ? length : tsg->BytesAvailable; CopyMemory(data, &tsg->pdu->s->buffer[tsg->BytesRead], CopyLength); tsg->BytesAvailable -= CopyLength; tsg->BytesRead += CopyLength; if (tsg->BytesAvailable < 1) { tsg->PendingPdu = FALSE; rpc_recv_dequeue_pdu(rpc); rpc_client_receive_pool_return(rpc, tsg->pdu); } return CopyLength; } else { tsg->pdu = rpc_recv_peek_pdu(rpc); if (!tsg->pdu) { if (tsg->rpc->client->SynchronousReceive) return tsg_read(tsg, data, length); else return 0; } tsg->PendingPdu = TRUE; tsg->BytesAvailable = Stream_Length(tsg->pdu->s); tsg->BytesRead = 0; CopyLength = (length < tsg->BytesAvailable) ? length : tsg->BytesAvailable; CopyMemory(data, &tsg->pdu->s->buffer[tsg->BytesRead], CopyLength); tsg->BytesAvailable -= CopyLength; tsg->BytesRead += CopyLength; if (tsg->BytesAvailable < 1) { tsg->PendingPdu = FALSE; rpc_recv_dequeue_pdu(rpc); rpc_client_receive_pool_return(rpc, tsg->pdu); } return CopyLength; } }
static int transport_bio_tsg_read(BIO* bio, char* buf, int size) { int status; rdpTsg* tsg; tsg = (rdpTsg*) bio->ptr; status = tsg_read(bio->ptr, (BYTE*) buf, size); BIO_clear_retry_flags(bio); if (status <= 0) { BIO_set_retry_read(bio); } return status > 0 ? status : -1; }
int transport_read_layer(rdpTransport* transport, BYTE* data, int bytes) { int read = 0; int status = -1; while (read < bytes) { if (transport->layer == TRANSPORT_LAYER_TLS) status = tls_read(transport->TlsIn, data + read, bytes - read); else if (transport->layer == TRANSPORT_LAYER_TCP) status = tcp_read(transport->TcpIn, data + read, bytes - read); else if (transport->layer == TRANSPORT_LAYER_TSG) status = tsg_read(transport->tsg, data + read, bytes - read); else if (transport->layer == TRANSPORT_LAYER_TSG_TLS) { status = tls_read(transport->TsgTls, data + read, bytes - read); } /* blocking means that we can't continue until this is read */ if (!transport->blocking) return status; if (status < 0) { /* A read error indicates that the peer has dropped the connection */ transport->layer = TRANSPORT_LAYER_CLOSED; return status; } read += status; if (status == 0) { /* * instead of sleeping, we should wait timeout on the * socket but this only happens on initial connection */ USleep(transport->SleepInterval); } } return read; }
static int transport_bio_tsg_read(BIO* bio, char* buf, int size) { int status; rdpTsg* tsg; tsg = (rdpTsg*) bio->ptr; BIO_clear_flags(bio, BIO_FLAGS_READ); status = tsg_read(bio->ptr, (BYTE*) buf, size); if (status < 0) { BIO_clear_flags(bio, BIO_FLAGS_SHOULD_RETRY); } else { BIO_set_flags(bio, BIO_FLAGS_READ); } return status >= 0 ? status : -1; }
static int transport_bio_tsg_read(BIO* bio, char* buf, int size) { int status; rdpTsg* tsg = (rdpTsg*) bio->ptr; BIO_clear_flags(bio, BIO_FLAGS_READ); status = tsg_read(tsg, (BYTE*) buf, size); if (status < 0) { BIO_clear_flags(bio, BIO_FLAGS_SHOULD_RETRY); } else if (status == 0) { BIO_set_flags(bio, BIO_FLAGS_SHOULD_RETRY); WSASetLastError(WSAEWOULDBLOCK); } else { BIO_set_flags(bio, BIO_FLAGS_READ); } return status > 0 ? status : -1; }
int tsg_read(rdpTsg* tsg, BYTE* data, UINT32 length) { int CopyLength; rdpRpc* rpc; if (tsg == NULL) return -1; rpc = tsg->rpc; if (rpc->transport->layer == TRANSPORT_LAYER_CLOSED) { DEBUG_WARN( "tsg_read error: connection lost\n"); return -1; } if (tsg->PendingPdu) { CopyLength = (length < tsg->BytesAvailable) ? length : tsg->BytesAvailable; CopyMemory(data, &tsg->pdu->s->buffer[tsg->BytesRead], CopyLength); tsg->BytesAvailable -= CopyLength; tsg->BytesRead += CopyLength; if (tsg->BytesAvailable < 1) { tsg->PendingPdu = FALSE; rpc_recv_dequeue_pdu(rpc); rpc_client_receive_pool_return(rpc, tsg->pdu); } return CopyLength; } tsg->pdu = rpc_recv_peek_pdu(rpc); if (!tsg->pdu) { if (!tsg->rpc->client->SynchronousReceive) return 0; // weird !!!! return tsg_read(tsg, data, length); } tsg->PendingPdu = TRUE; tsg->BytesAvailable = Stream_Length(tsg->pdu->s); tsg->BytesRead = 0; CopyLength = (length < tsg->BytesAvailable) ? length : tsg->BytesAvailable; CopyMemory(data, &tsg->pdu->s->buffer[tsg->BytesRead], CopyLength); tsg->BytesAvailable -= CopyLength; tsg->BytesRead += CopyLength; if (tsg->BytesAvailable < 1) { tsg->PendingPdu = FALSE; rpc_recv_dequeue_pdu(rpc); rpc_client_receive_pool_return(rpc, tsg->pdu); } return CopyLength; }