libfreerdp-core: implement tcp receiving.

This commit is contained in:
Vic Lee 2011-07-03 18:30:43 +08:00
parent addc192965
commit 6a3db6363d
3 changed files with 90 additions and 4 deletions

View File

@ -125,5 +125,11 @@ stream_extend(STREAM * stream);
*_s->ptr++ = ((_v) >> 8) & 0xFF; \
*_s->ptr++ = (_v) & 0xFF; } while (0)
#define stream_copy(_dst, _src, _n) do { \
memcpy(_dst->ptr, _src->ptr, _n); \
_dst->ptr += _n; \
_src->ptr += _n; \
} while (0)
#endif /* __STREAM_UTILS_H */

View File

@ -29,8 +29,11 @@
#include <netdb.h>
#include <fcntl.h>
#include "tpkt.h"
#include "transport.h"
#define BUFFER_SIZE 16384
rdpTransport *
transport_new(void)
{
@ -45,12 +48,16 @@ transport_new(void)
transport->ts.tv_sec = 0;
transport->ts.tv_nsec = 100000;
/* receive buffer for non-blocking read. */
transport->recv_buffer = stream_new(BUFFER_SIZE);
return transport;
}
void
transport_free(rdpTransport * transport)
{
stream_free(transport->recv_buffer);
xfree(transport);
}
@ -201,8 +208,78 @@ transport_send(rdpTransport * transport, STREAM * stream)
return transport_send_tcp(transport, stream);
}
int
transport_check_fds(rdpTransport * transport)
static int
transport_recv_tls(rdpTransport * transport)
{
return 0;
}
static int
transport_recv_tcp(rdpTransport * transport)
{
int r;
stream_check_capacity(transport->recv_buffer, BUFFER_SIZE);
r = recv(transport->sockfd, transport->recv_buffer->ptr, BUFFER_SIZE, 0);
if (r == -1)
{
if (errno == EAGAIN || errno == EWOULDBLOCK)
return 0;
printf("transport_recv_tcp: recv failed (%d).\n", errno);
return -1;
}
stream_seek(transport->recv_buffer, r);
return r;
}
int
transport_check_fds(rdpTransport * transport)
{
int r;
int pos;
uint16 len;
STREAM * received;
if (transport->tls)
r = transport_recv_tls(transport);
else
r = transport_recv_tcp(transport);
if (r <= 0)
return r;
pos = stream_get_pos(transport->recv_buffer);
/* Ensure the TPKT header is available. */
if (pos <= 4)
return 0;
stream_set_pos(transport->recv_buffer, 0);
len = tpkt_read_header(transport->recv_buffer);
if (len == 0)
{
printf("transport_check_fds: protocol error, not a TPKT header.\n");
return -1;
}
if (pos < len)
return 0; /* Packet is not yet completely received. */
/* A complete packet has been received. In case there are trailing data
* for the next packet, we copy it to the new receive buffer.
*/
received = transport->recv_buffer;
transport->recv_buffer = stream_new(BUFFER_SIZE);
if (pos > len)
{
stream_set_pos(received, len);
stream_check_capacity(transport->recv_buffer, pos - len);
stream_copy(transport->recv_buffer, received, pos - len);
}
stream_set_pos(received, 0);
r = transport->recv_callback(received, transport->recv_callback_data);
stream_free(received);
return r;
}

View File

@ -22,14 +22,17 @@
#include <freerdp/utils/stream.h>
typedef int (* PacketReceivedCallback) (STREAM * stream);
typedef int (* PacketReceivedCallback) (STREAM * stream, void * callback_data);
struct rdp_transport
{
int sockfd;
struct crypto_tls * tls;
PacketReceivedCallback * recv_callback;
struct timespec ts;
STREAM * recv_buffer;
PacketReceivedCallback recv_callback;
void * recv_callback_data;
};
typedef struct rdp_transport rdpTransport;