libfreerdp-core: moving TCP out of transport module
This commit is contained in:
parent
0da3be6e53
commit
347863ffa5
Binary file not shown.
@ -30,6 +30,8 @@ set(LIBFREERDP_CORE_SRCS
|
||||
# credssp.h
|
||||
# ntlmssp.c
|
||||
# ntlmssp.h
|
||||
tcp.c
|
||||
tcp.h
|
||||
tpdu.c
|
||||
tpdu.h
|
||||
tpkt.c
|
||||
|
@ -47,23 +47,21 @@ int nego_connect(rdpNego *nego)
|
||||
nego->state = NEGO_STATE_FAIL;
|
||||
}
|
||||
|
||||
DEBUG_NEGO("Negotiating protocol security");
|
||||
|
||||
while (nego->state != NEGO_STATE_FINAL)
|
||||
{
|
||||
nego_send(nego);
|
||||
|
||||
DEBUG_NEGO("state: %s", NEGO_STATE_STRINGS[nego->state]);
|
||||
|
||||
nego_send(nego);
|
||||
|
||||
if (nego->state == NEGO_STATE_FAIL)
|
||||
{
|
||||
nego->state = NEGO_STATE_FINAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
nego->state = NEGO_STATE_FINAL;
|
||||
}
|
||||
|
||||
DEBUG_NEGO("Negotiated %s security", PROTOCOL_SECURITY_STRINGS[nego->selected_protocol]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -215,6 +213,10 @@ int nego_recv(rdpTransport * transport, STREAM* s, void * extra)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nego->state = NEGO_STATE_FINAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -56,6 +56,13 @@ enum RDP_NEG_MSG
|
||||
TYPE_RDP_NEG_FAILURE = 0x3
|
||||
};
|
||||
|
||||
char PROTOCOL_SECURITY_STRINGS[3][4] =
|
||||
{
|
||||
"RDP",
|
||||
"TLS",
|
||||
"NLA"
|
||||
};
|
||||
|
||||
struct rdp_nego
|
||||
{
|
||||
int port;
|
||||
|
145
libfreerdp-core/tcp.c
Normal file
145
libfreerdp-core/tcp.c
Normal file
@ -0,0 +1,145 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* Transmission Control Protocol (TCP)
|
||||
*
|
||||
* Copyright 2011 Vic Lee
|
||||
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <freerdp/utils/stream.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
|
||||
#include "tcp.h"
|
||||
|
||||
FRDP_BOOL
|
||||
tcp_connect(rdpTcp * tcp, const char * hostname, int port)
|
||||
{
|
||||
int status;
|
||||
int sockfd = -1;
|
||||
char servname[10];
|
||||
struct addrinfo hints = { 0 };
|
||||
struct addrinfo * res, * ai;
|
||||
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
snprintf(servname, sizeof(servname), "%d", port);
|
||||
status = getaddrinfo(hostname, servname, &hints, &res);
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
printf("transport_connect: getaddrinfo (%s)\n", gai_strerror(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
for (ai = res; ai; ai = ai->ai_next)
|
||||
{
|
||||
sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
||||
|
||||
if (sockfd < 0)
|
||||
continue;
|
||||
|
||||
if (connect(sockfd, ai->ai_addr, ai->ai_addrlen) == 0)
|
||||
{
|
||||
printf("connected to %s:%s\n", hostname, servname);
|
||||
break;
|
||||
}
|
||||
|
||||
sockfd = -1;
|
||||
}
|
||||
freeaddrinfo(res);
|
||||
|
||||
if (sockfd == -1)
|
||||
{
|
||||
printf("unable to connect to %s:%s\n", hostname, servname);
|
||||
return False;
|
||||
}
|
||||
|
||||
tcp->sockfd = sockfd;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
FRDP_BOOL
|
||||
tcp_disconnect(rdpTcp * tcp)
|
||||
{
|
||||
if (tcp->sockfd != -1)
|
||||
{
|
||||
close(tcp->sockfd);
|
||||
tcp->sockfd = -1;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
FRDP_BOOL
|
||||
tcp_set_blocking_mode(rdpTcp * tcp, FRDP_BOOL blocking)
|
||||
{
|
||||
int flags;
|
||||
flags = fcntl(tcp->sockfd, F_GETFL);
|
||||
|
||||
if (flags == -1)
|
||||
{
|
||||
printf("transport_configure_sockfd: fcntl failed.\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
if (blocking == True)
|
||||
{
|
||||
/* blocking */
|
||||
fcntl(tcp->sockfd, F_SETFL, flags & ~(O_NONBLOCK));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* non-blocking */
|
||||
fcntl(tcp->sockfd, F_SETFL, flags | O_NONBLOCK);
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
rdpTcp*
|
||||
tcp_new()
|
||||
{
|
||||
rdpTcp *tcp = (rdpTcp*) xzalloc(sizeof(rdpTcp));
|
||||
|
||||
if (tcp != NULL)
|
||||
{
|
||||
tcp->sockfd = -1;
|
||||
tcp->connect = tcp_connect;
|
||||
tcp->disconnect = tcp_disconnect;
|
||||
tcp->set_blocking_mode = tcp_set_blocking_mode;
|
||||
}
|
||||
|
||||
return tcp;
|
||||
}
|
||||
|
||||
void
|
||||
tcp_free(rdpTcp* tcp)
|
||||
{
|
||||
if (tcp != NULL)
|
||||
{
|
||||
xfree(tcp);
|
||||
}
|
||||
}
|
52
libfreerdp-core/tcp.h
Normal file
52
libfreerdp-core/tcp.h
Normal file
@ -0,0 +1,52 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* Transmission Control Protocol (TCP)
|
||||
*
|
||||
* Copyright 2011 Vic Lee
|
||||
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __TCP_H
|
||||
#define __TCP_H
|
||||
|
||||
#include <freerdp/types/base.h>
|
||||
#include <freerdp/utils/stream.h>
|
||||
|
||||
typedef struct rdp_tcp rdpTcp;
|
||||
typedef FRDP_BOOL (*TcpConnect) (rdpTcp * tcp, const char * hostname, int port);
|
||||
typedef FRDP_BOOL (*TcpDisconnect) (rdpTcp * tcp);
|
||||
typedef FRDP_BOOL (*TcpSetBlockingMode) (rdpTcp * tcp, FRDP_BOOL blocking);
|
||||
|
||||
struct rdp_tcp
|
||||
{
|
||||
int sockfd;
|
||||
TcpConnect connect;
|
||||
TcpDisconnect disconnect;
|
||||
TcpSetBlockingMode set_blocking_mode;
|
||||
};
|
||||
|
||||
FRDP_BOOL
|
||||
tcp_connect(rdpTcp * tcp, const char * hostname, int port);
|
||||
FRDP_BOOL
|
||||
tcp_disconnect(rdpTcp * tcp);
|
||||
FRDP_BOOL
|
||||
tcp_set_blocking_mode(rdpTcp * tcp, FRDP_BOOL blocking);
|
||||
|
||||
rdpTcp*
|
||||
tcp_new();
|
||||
void
|
||||
tcp_free(rdpTcp* tcp);
|
||||
|
||||
#endif /* __TCP_H */
|
@ -34,122 +34,16 @@
|
||||
|
||||
#define BUFFER_SIZE 16384
|
||||
|
||||
rdpTransport *
|
||||
transport_new(void)
|
||||
{
|
||||
rdpTransport * transport;
|
||||
|
||||
transport = (rdpTransport *) xmalloc(sizeof(rdpTransport));
|
||||
memset(transport, 0, sizeof(rdpTransport));
|
||||
|
||||
transport->sockfd = -1;
|
||||
|
||||
/* a small 0.1ms delay when transport is blocking. */
|
||||
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);
|
||||
}
|
||||
|
||||
static FRDP_BOOL
|
||||
transport_connect_sockfd(rdpTransport * transport, const char * server, int port)
|
||||
{
|
||||
int status;
|
||||
int sockfd = -1;
|
||||
char servname[10];
|
||||
struct addrinfo hints = { 0 };
|
||||
struct addrinfo * res, * ai;
|
||||
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
snprintf(servname, sizeof(servname), "%d", port);
|
||||
status = getaddrinfo(server, servname, &hints, &res);
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
printf("transport_connect: getaddrinfo (%s)\n", gai_strerror(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
for (ai = res; ai; ai = ai->ai_next)
|
||||
{
|
||||
sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
||||
|
||||
if (sockfd < 0)
|
||||
continue;
|
||||
|
||||
if (connect(sockfd, ai->ai_addr, ai->ai_addrlen) == 0)
|
||||
{
|
||||
printf("connected to %s:%s\n", server, servname);
|
||||
break;
|
||||
}
|
||||
|
||||
sockfd = -1;
|
||||
}
|
||||
freeaddrinfo(res);
|
||||
|
||||
if (sockfd == -1)
|
||||
{
|
||||
printf("unable to connect to %s:%s\n", server, servname);
|
||||
return False;
|
||||
}
|
||||
|
||||
transport->sockfd = sockfd;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static FRDP_BOOL
|
||||
transport_configure_sockfd(rdpTransport * transport)
|
||||
{
|
||||
int flags;
|
||||
|
||||
flags = fcntl(transport->sockfd, F_GETFL);
|
||||
|
||||
if (flags == -1)
|
||||
{
|
||||
printf("transport_configure_sockfd: fcntl failed.\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
fcntl(transport->sockfd, F_SETFL, flags | O_NONBLOCK);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
FRDP_BOOL
|
||||
transport_connect(rdpTransport * transport, const char * server, int port)
|
||||
{
|
||||
if (transport_connect_sockfd(transport, server, port) != True)
|
||||
return False;
|
||||
|
||||
if (transport_configure_sockfd(transport) != True)
|
||||
return False;
|
||||
|
||||
return True;
|
||||
return transport->tcp->connect(transport->tcp, server, port);
|
||||
}
|
||||
|
||||
int
|
||||
FRDP_BOOL
|
||||
transport_disconnect(rdpTransport * transport)
|
||||
{
|
||||
if (transport->sockfd != -1)
|
||||
{
|
||||
close(transport->sockfd);
|
||||
transport->sockfd = -1;
|
||||
}
|
||||
|
||||
return True;
|
||||
return transport->tcp->disconnect(transport->tcp);
|
||||
}
|
||||
|
||||
int
|
||||
@ -183,7 +77,7 @@ transport_send_tcp(rdpTransport * transport, STREAM * stream)
|
||||
|
||||
while (head < tail)
|
||||
{
|
||||
bytes = send(transport->sockfd, head, tail - head, MSG_NOSIGNAL);
|
||||
bytes = send(transport->tcp->sockfd, head, tail - head, MSG_NOSIGNAL);
|
||||
|
||||
if (bytes < 0)
|
||||
{
|
||||
@ -226,7 +120,7 @@ transport_recv_tcp(rdpTransport * transport)
|
||||
|
||||
stream_check_capacity(transport->recv_buffer, BUFFER_SIZE);
|
||||
|
||||
bytes = recv(transport->sockfd, transport->recv_buffer->ptr, BUFFER_SIZE, 0);
|
||||
bytes = recv(transport->tcp->sockfd, transport->recv_buffer->ptr, BUFFER_SIZE, 0);
|
||||
|
||||
if (bytes == -1)
|
||||
{
|
||||
@ -296,3 +190,42 @@ transport_check_fds(rdpTransport * transport)
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
void
|
||||
transport_init(rdpTransport * transport)
|
||||
{
|
||||
transport->state = TRANSPORT_STATE_NEGO;
|
||||
}
|
||||
|
||||
rdpTransport *
|
||||
transport_new(void)
|
||||
{
|
||||
rdpTransport * transport;
|
||||
|
||||
transport = (rdpTransport *) xzalloc(sizeof(rdpTransport));
|
||||
|
||||
if (transport != NULL)
|
||||
{
|
||||
transport->tcp = tcp_new();
|
||||
|
||||
/* a small 0.1ms delay when transport is blocking. */
|
||||
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)
|
||||
{
|
||||
if (transport != NULL)
|
||||
{
|
||||
stream_free(transport->recv_buffer);
|
||||
tcp_free(transport->tcp);
|
||||
xfree(transport);
|
||||
}
|
||||
}
|
||||
|
@ -20,16 +20,29 @@
|
||||
#ifndef __TRANSPORT_H
|
||||
#define __TRANSPORT_H
|
||||
|
||||
#include "tcp.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <freerdp/types/base.h>
|
||||
#include <freerdp/utils/stream.h>
|
||||
|
||||
enum _TRANSPORT_STATE
|
||||
{
|
||||
TRANSPORT_STATE_INITIAL,
|
||||
TRANSPORT_STATE_NEGO,
|
||||
TRANSPORT_STATE_TLS,
|
||||
TRANSPORT_STATE_NLA,
|
||||
TRANSPORT_STATE_FINAL
|
||||
};
|
||||
typedef enum _TRANSPORT_STATE TRANSPORT_STATE;
|
||||
|
||||
typedef struct rdp_transport rdpTransport;
|
||||
typedef int (* PacketReceivedCallback) (rdpTransport * transport, STREAM * stream, void* extra);
|
||||
|
||||
struct rdp_transport
|
||||
{
|
||||
int sockfd;
|
||||
TRANSPORT_STATE state;
|
||||
struct rdp_tcp * tcp;
|
||||
struct crypto_tls * tls;
|
||||
struct timespec ts;
|
||||
STREAM * recv_buffer;
|
||||
|
Loading…
Reference in New Issue
Block a user