int transport_write(rdpTransport* transport, STREAM* s) { int status = -1; int length; length = stream_get_length(s); stream_set_pos(s, 0); #ifdef WITH_DEBUG_TRANSPORT if (length > 0) { printf("Local > Remote\n"); winpr_HexDump(s->data, length); } #endif while (length > 0) { if (transport->layer == TRANSPORT_LAYER_TLS) status = tls_write(transport->TlsOut, stream_get_tail(s), length); else if (transport->layer == TRANSPORT_LAYER_TCP) status = tcp_write(transport->TcpOut, stream_get_tail(s), length); else if (transport->layer == TRANSPORT_LAYER_TSG) status = tsg_write(transport->tsg, stream_get_tail(s), length); if (status < 0) break; /* error occurred */ if (status == 0) { /* when sending is blocked in nonblocking mode, the receiving buffer should be checked */ if (!transport->blocking) { /* and in case we do have buffered some data, we set the event so next loop will get it */ if (transport_read_nonblocking(transport) > 0) SetEvent(transport->ReceiveEvent); } if (transport->layer == TRANSPORT_LAYER_TLS) tls_wait_write(transport->TlsOut); else if (transport->layer == TRANSPORT_LAYER_TCP) tcp_wait_write(transport->TcpOut); else USleep(transport->SleepInterval); } length -= status; stream_seek(s, status); } if (status < 0) { /* A write error indicates that the peer has dropped the connection */ transport->layer = TRANSPORT_LAYER_CLOSED; } return status; }
int tls_write_all(rdpTls* tls, BYTE* data, int length) { int status; int sent = 0; do { status = tls_write(tls, &data[sent], length - sent); if (status > 0) sent += status; else if (status == 0) tls_wait_write(tls); if (sent >= length) break; } while (status >= 0); if (status > 0) return length; else return status; }
int transport_write(rdpTransport* transport, wStream* s) { int length; int status = -1; WaitForSingleObject(transport->WriteMutex, INFINITE); length = Stream_GetPosition(s); Stream_SetPosition(s, 0); #ifdef WITH_DEBUG_TRANSPORT if (length > 0) { fprintf(stderr, "Local > Remote\n"); winpr_HexDump(Stream_Buffer(s), length); } #endif if (length > 0) { WLog_Packet(transport->log, WLOG_TRACE, Stream_Buffer(s), length, WLOG_PACKET_OUTBOUND); } while (length > 0) { if (transport->layer == TRANSPORT_LAYER_TLS) status = tls_write(transport->TlsOut, Stream_Pointer(s), length); else if (transport->layer == TRANSPORT_LAYER_TCP) status = tcp_write(transport->TcpOut, Stream_Pointer(s), length); else if (transport->layer == TRANSPORT_LAYER_TSG) status = tsg_write(transport->tsg, Stream_Pointer(s), length); else if (transport->layer == TRANSPORT_LAYER_TSG_TLS) status = tls_write(transport->TsgTls, Stream_Pointer(s), length); if (status < 0) break; /* error occurred */ if (status == 0) { /* when sending is blocked in nonblocking mode, the receiving buffer should be checked */ if (!transport->blocking) { /* and in case we do have buffered some data, we set the event so next loop will get it */ if (transport_read_nonblocking(transport) > 0) SetEvent(transport->ReceiveEvent); } if (transport->layer == TRANSPORT_LAYER_TLS) tls_wait_write(transport->TlsOut); else if (transport->layer == TRANSPORT_LAYER_TCP) tcp_wait_write(transport->TcpOut); else if (transport->layer == TRANSPORT_LAYER_TSG_TLS) tls_wait_write(transport->TsgTls); else USleep(transport->SleepInterval); } length -= status; Stream_Seek(s, status); } if (status < 0) { /* A write error indicates that the peer has dropped the connection */ transport->layer = TRANSPORT_LAYER_CLOSED; } if (s->pool) Stream_Release(s); ReleaseMutex(transport->WriteMutex); return status; }