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
|
# credssp.h
|
||||||
# ntlmssp.c
|
# ntlmssp.c
|
||||||
# ntlmssp.h
|
# ntlmssp.h
|
||||||
|
tcp.c
|
||||||
|
tcp.h
|
||||||
tpdu.c
|
tpdu.c
|
||||||
tpdu.h
|
tpdu.h
|
||||||
tpkt.c
|
tpkt.c
|
||||||
|
@ -47,23 +47,21 @@ int nego_connect(rdpNego *nego)
|
|||||||
nego->state = NEGO_STATE_FAIL;
|
nego->state = NEGO_STATE_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_NEGO("Negotiating protocol security");
|
|
||||||
|
|
||||||
while (nego->state != NEGO_STATE_FINAL)
|
while (nego->state != NEGO_STATE_FINAL)
|
||||||
{
|
{
|
||||||
nego_send(nego);
|
|
||||||
|
|
||||||
DEBUG_NEGO("state: %s", NEGO_STATE_STRINGS[nego->state]);
|
DEBUG_NEGO("state: %s", NEGO_STATE_STRINGS[nego->state]);
|
||||||
|
|
||||||
|
nego_send(nego);
|
||||||
|
|
||||||
if (nego->state == NEGO_STATE_FAIL)
|
if (nego->state == NEGO_STATE_FAIL)
|
||||||
{
|
{
|
||||||
nego->state = NEGO_STATE_FINAL;
|
nego->state = NEGO_STATE_FINAL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
nego->state = NEGO_STATE_FINAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEBUG_NEGO("Negotiated %s security", PROTOCOL_SECURITY_STRINGS[nego->selected_protocol]);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,6 +213,10 @@ int nego_recv(rdpTransport * transport, STREAM* s, void * extra)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nego->state = NEGO_STATE_FINAL;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -38,12 +38,12 @@ typedef enum _NEGO_STATE NEGO_STATE;
|
|||||||
|
|
||||||
char NEGO_STATE_STRINGS[6][25] =
|
char NEGO_STATE_STRINGS[6][25] =
|
||||||
{
|
{
|
||||||
"NEGO_STATE_INITIAL",
|
"NEGO_STATE_INITIAL",
|
||||||
"NEGO_STATE_NLA",
|
"NEGO_STATE_NLA",
|
||||||
"NEGO_STATE_TLS",
|
"NEGO_STATE_TLS",
|
||||||
"NEGO_STATE_RDP",
|
"NEGO_STATE_RDP",
|
||||||
"NEGO_STATE_FAIL",
|
"NEGO_STATE_FAIL",
|
||||||
"NEGO_STATE_FINAL"
|
"NEGO_STATE_FINAL"
|
||||||
};
|
};
|
||||||
|
|
||||||
/* RDP Negotiation Messages */
|
/* RDP Negotiation Messages */
|
||||||
@ -56,6 +56,13 @@ enum RDP_NEG_MSG
|
|||||||
TYPE_RDP_NEG_FAILURE = 0x3
|
TYPE_RDP_NEG_FAILURE = 0x3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
char PROTOCOL_SECURITY_STRINGS[3][4] =
|
||||||
|
{
|
||||||
|
"RDP",
|
||||||
|
"TLS",
|
||||||
|
"NLA"
|
||||||
|
};
|
||||||
|
|
||||||
struct rdp_nego
|
struct rdp_nego
|
||||||
{
|
{
|
||||||
int port;
|
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
|
#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
|
FRDP_BOOL
|
||||||
transport_connect(rdpTransport * transport, const char * server, int port)
|
transport_connect(rdpTransport * transport, const char * server, int port)
|
||||||
{
|
{
|
||||||
if (transport_connect_sockfd(transport, server, port) != True)
|
return transport->tcp->connect(transport->tcp, server, port);
|
||||||
return False;
|
|
||||||
|
|
||||||
if (transport_configure_sockfd(transport) != True)
|
|
||||||
return False;
|
|
||||||
|
|
||||||
return True;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
FRDP_BOOL
|
||||||
transport_disconnect(rdpTransport * transport)
|
transport_disconnect(rdpTransport * transport)
|
||||||
{
|
{
|
||||||
if (transport->sockfd != -1)
|
return transport->tcp->disconnect(transport->tcp);
|
||||||
{
|
|
||||||
close(transport->sockfd);
|
|
||||||
transport->sockfd = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return True;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -183,7 +77,7 @@ transport_send_tcp(rdpTransport * transport, STREAM * stream)
|
|||||||
|
|
||||||
while (head < tail)
|
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)
|
if (bytes < 0)
|
||||||
{
|
{
|
||||||
@ -226,7 +120,7 @@ transport_recv_tcp(rdpTransport * transport)
|
|||||||
|
|
||||||
stream_check_capacity(transport->recv_buffer, BUFFER_SIZE);
|
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)
|
if (bytes == -1)
|
||||||
{
|
{
|
||||||
@ -296,3 +190,42 @@ transport_check_fds(rdpTransport * transport)
|
|||||||
|
|
||||||
return bytes;
|
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
|
#ifndef __TRANSPORT_H
|
||||||
#define __TRANSPORT_H
|
#define __TRANSPORT_H
|
||||||
|
|
||||||
|
#include "tcp.h"
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <freerdp/types/base.h>
|
#include <freerdp/types/base.h>
|
||||||
#include <freerdp/utils/stream.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 struct rdp_transport rdpTransport;
|
||||||
typedef int (* PacketReceivedCallback) (rdpTransport * transport, STREAM * stream, void* extra);
|
typedef int (* PacketReceivedCallback) (rdpTransport * transport, STREAM * stream, void* extra);
|
||||||
|
|
||||||
struct rdp_transport
|
struct rdp_transport
|
||||||
{
|
{
|
||||||
int sockfd;
|
TRANSPORT_STATE state;
|
||||||
|
struct rdp_tcp * tcp;
|
||||||
struct crypto_tls * tls;
|
struct crypto_tls * tls;
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
STREAM * recv_buffer;
|
STREAM * recv_buffer;
|
||||||
|
Loading…
Reference in New Issue
Block a user