21 #include <freerdp/config.h>
29 #include <winpr/crt.h>
30 #include <winpr/platform.h>
31 #include <winpr/winsock.h>
40 #include <sys/ioctl.h>
41 #include <sys/socket.h>
42 #include <netinet/in.h>
43 #include <netinet/tcp.h>
45 #include <sys/types.h>
46 #include <arpa/inet.h>
48 #ifdef WINPR_HAVE_POLL_H
52 #include <sys/select.h>
55 #if defined(__FreeBSD__) || defined(__OpenBSD__)
57 #define SOL_TCP IPPROTO_TCP
63 #define SOL_TCP IPPROTO_TCP
66 #define TCP_KEEPIDLE TCP_KEEPALIVE
72 #include <winpr/windows.h>
74 #include <winpr/crt.h>
76 #define SHUT_RDWR SD_BOTH
77 #define close(_fd) closesocket(_fd)
81 #include <freerdp/log.h>
83 #include <winpr/stream.h>
86 #include "../crypto/opensslcompat.h"
88 #if defined(HAVE_AF_VSOCK_H)
90 #include <linux/vm_sockets.h>
93 #define TAG FREERDP_TAG("core")
101 } WINPR_BIO_SIMPLE_SOCKET;
103 static int transport_bio_simple_init(BIO* bio, SOCKET socket,
int shutdown);
104 static int transport_bio_simple_uninit(BIO* bio);
106 static long transport_bio_simple_callback(BIO* bio,
int mode,
const char* argp,
int argi,
long argl,
112 static int transport_bio_simple_write(BIO* bio,
const char* buf,
int size)
116 WINPR_BIO_SIMPLE_SOCKET* ptr = (WINPR_BIO_SIMPLE_SOCKET*)BIO_get_data(bio);
121 BIO_clear_flags(bio, BIO_FLAGS_WRITE);
122 status = _send(ptr->socket, buf, size, 0);
126 error = WSAGetLastError();
128 if ((error == WSAEWOULDBLOCK) || (error == WSAEINTR) || (error == WSAEINPROGRESS) ||
129 (error == WSAEALREADY))
131 BIO_set_flags(bio, (BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY));
135 BIO_clear_flags(bio, BIO_FLAGS_SHOULD_RETRY);
142 static int transport_bio_simple_read(BIO* bio,
char* buf,
int size)
146 WINPR_BIO_SIMPLE_SOCKET* ptr = (WINPR_BIO_SIMPLE_SOCKET*)BIO_get_data(bio);
151 BIO_clear_flags(bio, BIO_FLAGS_READ);
152 (void)WSAResetEvent(ptr->hEvent);
153 status = _recv(ptr->socket, buf, size, 0);
162 BIO_clear_flags(bio, BIO_FLAGS_SHOULD_RETRY);
166 error = WSAGetLastError();
168 if ((error == WSAEWOULDBLOCK) || (error == WSAEINTR) || (error == WSAEINPROGRESS) ||
169 (error == WSAEALREADY))
171 BIO_set_flags(bio, (BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY));
175 BIO_clear_flags(bio, BIO_FLAGS_SHOULD_RETRY);
181 static int transport_bio_simple_puts(BIO* bio,
const char* str)
186 static int transport_bio_simple_gets(BIO* bio,
char* str,
int size)
191 static long transport_bio_simple_ctrl(BIO* bio,
int cmd,
long arg1,
void* arg2)
194 WINPR_BIO_SIMPLE_SOCKET* ptr = (WINPR_BIO_SIMPLE_SOCKET*)BIO_get_data(bio);
198 case BIO_C_SET_SOCKET:
199 transport_bio_simple_uninit(bio);
200 transport_bio_simple_init(bio, (SOCKET)arg2, (
int)arg1);
202 case BIO_C_GET_SOCKET:
203 if (!BIO_get_init(bio) || !arg2)
206 *((SOCKET*)arg2) = ptr->socket;
208 case BIO_C_GET_EVENT:
209 if (!BIO_get_init(bio) || !arg2)
212 *((HANDLE*)arg2) = ptr->hEvent;
214 case BIO_C_SET_NONBLOCK:
218 flags = fcntl((
int)ptr->socket, F_GETFL);
224 (void)fcntl((
int)ptr->socket, F_SETFL, flags | O_NONBLOCK);
226 (
void)fcntl((
int)ptr->socket, F_SETFL, flags & ~(O_NONBLOCK));
233 case BIO_C_WAIT_READ:
235 int timeout = (int)arg1;
236 int sockfd = (int)ptr->socket;
237 #ifdef WINPR_HAVE_POLL_H
238 struct pollfd pollset;
240 pollset.events = POLLIN;
245 status = poll(&pollset, 1, timeout);
246 }
while ((status < 0) && (errno == EINTR));
250 struct timeval tv = { 0 };
252 FD_SET(sockfd, &rset);
256 tv.tv_sec = timeout / 1000;
257 tv.tv_usec = (timeout % 1000) * 1000;
262 status = select(sockfd + 1, &rset, NULL, NULL, timeout ? &tv : NULL);
263 }
while ((status < 0) && (errno == EINTR));
272 case BIO_C_WAIT_WRITE:
274 int timeout = (int)arg1;
275 int sockfd = (int)ptr->socket;
276 #ifdef WINPR_HAVE_POLL_H
277 struct pollfd pollset;
279 pollset.events = POLLOUT;
284 status = poll(&pollset, 1, timeout);
285 }
while ((status < 0) && (errno == EINTR));
289 struct timeval tv = { 0 };
291 FD_SET(sockfd, &rset);
295 tv.tv_sec = timeout / 1000;
296 tv.tv_usec = (timeout % 1000) * 1000;
301 status = select(sockfd + 1, NULL, &rset, NULL, timeout ? &tv : NULL);
302 }
while ((status < 0) && (errno == EINTR));
314 transport_bio_simple_uninit(bio);
315 transport_bio_simple_init(bio, (SOCKET) * ((
int*)arg2), (
int)arg1);
322 if (BIO_get_init(bio))
325 *((
int*)arg2) = (int)ptr->socket;
327 status = (
int)ptr->socket;
332 case BIO_CTRL_GET_CLOSE:
333 status = BIO_get_shutdown(bio);
336 case BIO_CTRL_SET_CLOSE:
337 BIO_set_shutdown(bio, (
int)arg1);
354 static int transport_bio_simple_init(BIO* bio, SOCKET socket,
int shutdown)
356 WINPR_BIO_SIMPLE_SOCKET* ptr = (WINPR_BIO_SIMPLE_SOCKET*)BIO_get_data(bio);
357 ptr->socket = socket;
358 BIO_set_shutdown(bio, shutdown);
359 BIO_set_flags(bio, BIO_FLAGS_SHOULD_RETRY);
360 BIO_set_init(bio, 1);
361 ptr->hEvent = WSACreateEvent();
367 if (WSAEventSelect(ptr->socket, ptr->hEvent, FD_READ | FD_ACCEPT | FD_CLOSE))
369 WLog_ERR(TAG,
"WSAEventSelect returned 0x%08X", WSAGetLastError());
376 static int transport_bio_simple_uninit(BIO* bio)
378 WINPR_BIO_SIMPLE_SOCKET* ptr = (WINPR_BIO_SIMPLE_SOCKET*)BIO_get_data(bio);
380 if (BIO_get_shutdown(bio))
382 if (BIO_get_init(bio) && ptr)
384 _shutdown(ptr->socket, SD_BOTH);
385 closesocket(ptr->socket);
390 if (ptr && ptr->hEvent)
392 (void)CloseHandle(ptr->hEvent);
396 BIO_set_init(bio, 0);
397 BIO_set_flags(bio, 0);
401 static int transport_bio_simple_new(BIO* bio)
403 WINPR_BIO_SIMPLE_SOCKET* ptr = NULL;
404 BIO_set_flags(bio, BIO_FLAGS_SHOULD_RETRY);
405 ptr = (WINPR_BIO_SIMPLE_SOCKET*)calloc(1,
sizeof(WINPR_BIO_SIMPLE_SOCKET));
410 BIO_set_data(bio, ptr);
414 static int transport_bio_simple_free(BIO* bio)
416 WINPR_BIO_SIMPLE_SOCKET* ptr = NULL;
421 transport_bio_simple_uninit(bio);
422 ptr = (WINPR_BIO_SIMPLE_SOCKET*)BIO_get_data(bio);
426 BIO_set_data(bio, NULL);
433 BIO_METHOD* BIO_s_simple_socket(
void)
435 static BIO_METHOD* bio_methods = NULL;
437 if (bio_methods == NULL)
439 if (!(bio_methods = BIO_meth_new(BIO_TYPE_SIMPLE,
"SimpleSocket")))
442 BIO_meth_set_write(bio_methods, transport_bio_simple_write);
443 BIO_meth_set_read(bio_methods, transport_bio_simple_read);
444 BIO_meth_set_puts(bio_methods, transport_bio_simple_puts);
445 BIO_meth_set_gets(bio_methods, transport_bio_simple_gets);
446 BIO_meth_set_ctrl(bio_methods, transport_bio_simple_ctrl);
447 BIO_meth_set_create(bio_methods, transport_bio_simple_new);
448 BIO_meth_set_destroy(bio_methods, transport_bio_simple_free);
462 } WINPR_BIO_BUFFERED_SOCKET;
464 static long transport_bio_buffered_callback(BIO* bio,
int mode,
const char* argp,
int argi,
470 static int transport_bio_buffered_write(BIO* bio,
const char* buf,
int num)
474 size_t committedBytes = 0;
476 WINPR_BIO_BUFFERED_SOCKET* ptr = (WINPR_BIO_BUFFERED_SOCKET*)BIO_get_data(bio);
477 BIO* next_bio = NULL;
484 ptr->writeBlocked = FALSE;
485 BIO_clear_flags(bio, BIO_FLAGS_WRITE);
490 if (buf && (num > 0) && !ringbuffer_write(&ptr->xmitBuffer, (
const BYTE*)buf, (
size_t)num))
492 WLog_ERR(TAG,
"an error occurred when writing (num: %d)", num);
496 nchunks = ringbuffer_peek(&ptr->xmitBuffer, chunks, ringbuffer_used(&ptr->xmitBuffer));
497 next_bio = BIO_next(bio);
499 for (
int i = 0; i < nchunks; i++)
501 while (chunks[i].size)
505 const size_t wr = MIN(INT32_MAX, chunks[i].size);
506 const int status = BIO_write(next_bio, chunks[i].data, (
int)wr);
510 if (!BIO_should_retry(next_bio))
512 BIO_clear_flags(bio, BIO_FLAGS_SHOULD_RETRY);
517 if (BIO_should_write(next_bio))
519 BIO_set_flags(bio, BIO_FLAGS_WRITE);
520 ptr->writeBlocked = TRUE;
526 committedBytes += (size_t)status;
527 chunks[i].size -= (size_t)status;
528 chunks[i].data += status;
534 ringbuffer_commit_read_bytes(&ptr->xmitBuffer, committedBytes);
538 static int transport_bio_buffered_read(BIO* bio,
char* buf,
int size)
541 WINPR_BIO_BUFFERED_SOCKET* ptr = (WINPR_BIO_BUFFERED_SOCKET*)BIO_get_data(bio);
542 BIO* next_bio = BIO_next(bio);
543 ptr->readBlocked = FALSE;
544 BIO_clear_flags(bio, BIO_FLAGS_READ);
546 status = BIO_read(next_bio, buf, size);
550 if (!BIO_should_retry(next_bio))
552 BIO_clear_flags(bio, BIO_FLAGS_SHOULD_RETRY);
556 BIO_set_flags(bio, BIO_FLAGS_SHOULD_RETRY);
558 if (BIO_should_read(next_bio))
560 BIO_set_flags(bio, BIO_FLAGS_READ);
561 ptr->readBlocked = TRUE;
570 static int transport_bio_buffered_puts(BIO* bio,
const char* str)
575 static int transport_bio_buffered_gets(BIO* bio,
char* str,
int size)
580 static long transport_bio_buffered_ctrl(BIO* bio,
int cmd,
long arg1,
void* arg2)
583 WINPR_BIO_BUFFERED_SOCKET* ptr = (WINPR_BIO_BUFFERED_SOCKET*)BIO_get_data(bio);
588 if (!ringbuffer_used(&ptr->xmitBuffer))
591 status = (transport_bio_buffered_write(bio, NULL, 0) >= 0) ? 1 : -1;
595 case BIO_CTRL_WPENDING:
596 status = WINPR_ASSERTING_INT_CAST(
long, ringbuffer_used(&ptr->xmitBuffer));
599 case BIO_CTRL_PENDING:
603 case BIO_C_READ_BLOCKED:
604 status = (int)ptr->readBlocked;
607 case BIO_C_WRITE_BLOCKED:
608 status = (
int)ptr->writeBlocked;
612 status = BIO_ctrl(BIO_next(bio), cmd, arg1, arg2);
619 static int transport_bio_buffered_new(BIO* bio)
621 WINPR_BIO_BUFFERED_SOCKET* ptr = NULL;
622 BIO_set_init(bio, 1);
623 BIO_set_flags(bio, BIO_FLAGS_SHOULD_RETRY);
624 ptr = (WINPR_BIO_BUFFERED_SOCKET*)calloc(1,
sizeof(WINPR_BIO_BUFFERED_SOCKET));
629 BIO_set_data(bio, (
void*)ptr);
631 if (!ringbuffer_init(&ptr->xmitBuffer, 0x10000))
640 static int transport_bio_buffered_free(BIO* bio)
642 WINPR_BIO_BUFFERED_SOCKET* ptr = (WINPR_BIO_BUFFERED_SOCKET*)BIO_get_data(bio);
647 ringbuffer_destroy(&ptr->xmitBuffer);
652 BIO_METHOD* BIO_s_buffered_socket(
void)
654 static BIO_METHOD* bio_methods = NULL;
656 if (bio_methods == NULL)
658 if (!(bio_methods = BIO_meth_new(BIO_TYPE_BUFFERED,
"BufferedSocket")))
661 BIO_meth_set_write(bio_methods, transport_bio_buffered_write);
662 BIO_meth_set_read(bio_methods, transport_bio_buffered_read);
663 BIO_meth_set_puts(bio_methods, transport_bio_buffered_puts);
664 BIO_meth_set_gets(bio_methods, transport_bio_buffered_gets);
665 BIO_meth_set_ctrl(bio_methods, transport_bio_buffered_ctrl);
666 BIO_meth_set_create(bio_methods, transport_bio_buffered_new);
667 BIO_meth_set_destroy(bio_methods, transport_bio_buffered_free);
673 char* freerdp_tcp_address_to_string(
const struct sockaddr_storage* addr, BOOL* pIPv6)
675 char ipAddress[INET6_ADDRSTRLEN + 1] = { 0 };
676 const struct sockaddr_in6* sockaddr_ipv6 = (
const struct sockaddr_in6*)addr;
677 const struct sockaddr_in* sockaddr_ipv4 = (
const struct sockaddr_in*)addr;
684 switch (sockaddr_ipv4->sin_family)
687 if (!inet_ntop(sockaddr_ipv4->sin_family, &sockaddr_ipv4->sin_addr, ipAddress,
694 if (!inet_ntop(sockaddr_ipv6->sin6_family, &sockaddr_ipv6->sin6_addr, ipAddress,
701 (void)sprintf_s(ipAddress, ARRAYSIZE(ipAddress),
"127.0.0.1");
710 *pIPv6 = (sockaddr_ipv4->sin_family == AF_INET6);
713 return _strdup(ipAddress);
716 static char* freerdp_tcp_get_ip_address(
int sockfd, BOOL* pIPv6)
718 struct sockaddr_storage saddr = { 0 };
719 socklen_t length =
sizeof(
struct sockaddr_storage);
721 if (getsockname(sockfd, (
struct sockaddr*)&saddr, &length) != 0)
726 return freerdp_tcp_address_to_string(&saddr, pIPv6);
729 char* freerdp_tcp_get_peer_address(SOCKET sockfd)
731 struct sockaddr_storage saddr = { 0 };
732 socklen_t length =
sizeof(
struct sockaddr_storage);
734 if (getpeername((
int)sockfd, (
struct sockaddr*)&saddr, &length) != 0)
739 return freerdp_tcp_address_to_string(&saddr, NULL);
742 static int freerdp_uds_connect(
const char* path)
747 struct sockaddr_un addr = { 0 };
748 sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
752 WLog_ERR(TAG,
"socket");
756 addr.sun_family = AF_UNIX;
757 strncpy(addr.sun_path, path,
sizeof(addr.sun_path) - 1);
758 status = connect(sockfd, (
struct sockaddr*)&addr,
sizeof(addr));
762 WLog_ERR(TAG,
"connect");
773 struct addrinfo* freerdp_tcp_resolve_host(
const char* hostname,
int port,
int ai_flags)
775 char* service = NULL;
778 struct addrinfo hints = { 0 };
779 struct addrinfo* result = NULL;
780 hints.ai_family = AF_UNSPEC;
781 hints.ai_socktype = SOCK_STREAM;
782 hints.ai_flags = ai_flags;
786 (void)sprintf_s(port_str,
sizeof(port_str) - 1,
"%d", port);
790 status = getaddrinfo(hostname, service, &hints, &result);
798 static BOOL freerdp_tcp_is_hostname_resolvable(rdpContext* context,
const char* hostname)
800 struct addrinfo* result = freerdp_tcp_resolve_host(hostname, -1, 0);
804 freerdp_set_last_error_if_not(context, FREERDP_ERROR_DNS_NAME_NOT_FOUND);
809 freerdp_set_last_error_log(context, 0);
810 freeaddrinfo(result);
814 static BOOL freerdp_tcp_connect_timeout(rdpContext* context,
int sockfd,
struct sockaddr* addr,
815 socklen_t addrlen, UINT32 timeout)
818 HANDLE handles[2] = { 0 };
821 DWORD tout = (timeout > 0) ? timeout : INFINITE;
823 handles[count] = CreateEvent(NULL, TRUE, FALSE, NULL);
828 const int wsastatus = WSAEventSelect((SOCKET)sockfd, handles[count++],
829 FD_READ | FD_WRITE | FD_CONNECT | FD_CLOSE);
833 WLog_ERR(TAG,
"WSAEventSelect failed with %d", WSAGetLastError());
837 handles[count++] = utils_get_abort_event(context->rdp);
838 const int constatus = _connect((SOCKET)sockfd, addr, WINPR_ASSERTING_INT_CAST(
int, addrlen));
842 const int estatus = WSAGetLastError();
855 const DWORD wstatus = WaitForMultipleObjects(count, handles, FALSE, tout);
857 if (WAIT_OBJECT_0 != wstatus)
860 const SSIZE_T res = recv(sockfd, NULL, 0, 0);
862 if (res == SOCKET_ERROR)
864 if (WSAGetLastError() == WSAECONNRESET)
868 const int status = WSAEventSelect((SOCKET)sockfd, handles[0], 0);
872 WLog_ERR(TAG,
"WSAEventSelect failed with %d", WSAGetLastError());
876 if (_ioctlsocket((SOCKET)sockfd, FIONBIO, &arg) != 0)
881 (void)CloseHandle(handles[0]);
888 struct addrinfo* addr;
889 struct addrinfo* result;
892 static void peer_free(t_peer* peer)
894 if (peer->s != INVALID_SOCKET)
895 closesocket(peer->s);
897 freeaddrinfo(peer->addr);
898 memset(peer, 0,
sizeof(t_peer));
899 peer->s = INVALID_SOCKET;
902 static int freerdp_tcp_connect_multi(rdpContext* context,
char** hostnames,
const UINT32* ports,
903 UINT32 count, UINT16 port, UINT32 timeout)
905 UINT32 sindex = count;
906 SOCKET sockfd = INVALID_SOCKET;
907 struct addrinfo* addr = NULL;
908 struct addrinfo* result = NULL;
910 HANDLE* events = (HANDLE*)calloc(count + 1,
sizeof(HANDLE));
911 t_peer* peers = (t_peer*)calloc(count,
sizeof(t_peer));
913 if (!peers || !events || (count < 1))
920 for (UINT32 index = 0; index < count; index++)
925 curPort = WINPR_ASSERTING_INT_CAST(
int, ports[index]);
927 result = freerdp_tcp_resolve_host(hostnames[index], curPort, 0);
934 if ((addr->ai_family == AF_INET6) && (addr->ai_next != 0))
936 while ((addr = addr->ai_next))
938 if (addr->ai_family == AF_INET)
946 peers[index].s = _socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
948 if (peers[index].s == INVALID_SOCKET)
950 freeaddrinfo(result);
954 peers[index].addr = addr;
955 peers[index].result = result;
958 for (UINT32 index = 0; index < count; index++)
960 sockfd = peers[index].s;
961 addr = peers[index].addr;
963 if ((sockfd == INVALID_SOCKET) || (!addr))
968 _connect(sockfd, addr->ai_addr, WINPR_ASSERTING_INT_CAST(
int, addr->ai_addrlen));
980 sockfd = peers[sindex].s;
981 peers[sindex].s = INVALID_SOCKET;
984 freerdp_set_last_error_log(context, FREERDP_ERROR_CONNECT_CANCELLED);
986 for (UINT32 index = 0; index < count; index++)
987 peer_free(&peers[index]);
994 BOOL freerdp_tcp_set_keep_alive_mode(
const rdpSettings* settings,
int sockfd)
998 socklen_t optlen = 0;
999 optval = keepalive ? 1 : 0;
1000 optlen =
sizeof(optval);
1002 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (
void*)&optval, optlen) < 0)
1004 WLog_WARN(TAG,
"setsockopt() SOL_SOCKET, SO_KEEPALIVE");
1010 optlen =
sizeof(optval);
1012 if (setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE, (
void*)&optval, optlen) < 0)
1014 WLog_WARN(TAG,
"setsockopt() IPPROTO_TCP, TCP_KEEPIDLE");
1024 optlen =
sizeof(optval);
1026 if (setsockopt(sockfd, SOL_TCP, TCP_KEEPCNT, (
void*)&optval, optlen) < 0)
1028 WLog_WARN(TAG,
"setsockopt() SOL_TCP, TCP_KEEPCNT");
1032 #ifdef TCP_KEEPINTVL
1034 optlen =
sizeof(optval);
1036 if (setsockopt(sockfd, SOL_TCP, TCP_KEEPINTVL, (
void*)&optval, optlen) < 0)
1038 WLog_WARN(TAG,
"setsockopt() SOL_TCP, TCP_KEEPINTVL");
1043 #if defined(__MACOSX__) || defined(__IOS__)
1045 optlen =
sizeof(optval);
1047 if (setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (
void*)&optval, optlen) < 0)
1049 WLog_WARN(TAG,
"setsockopt() SOL_SOCKET, SO_NOSIGPIPE");
1053 #ifdef TCP_USER_TIMEOUT
1055 optlen =
sizeof(optval);
1057 if (setsockopt(sockfd, SOL_TCP, TCP_USER_TIMEOUT, (
void*)&optval, optlen) < 0)
1059 WLog_WARN(TAG,
"setsockopt() SOL_TCP, TCP_USER_TIMEOUT");
1066 int freerdp_tcp_connect(rdpContext* context,
const char* hostname,
int port, DWORD timeout)
1068 rdpTransport* transport = NULL;
1069 if (!context || !context->rdp)
1071 transport = context->rdp->transport;
1074 return transport_tcp_connect(context->rdp->transport, hostname, port, timeout);
1077 static int get_next_addrinfo(rdpContext* context,
struct addrinfo* input,
struct addrinfo** result,
1080 WINPR_ASSERT(context);
1081 WINPR_ASSERT(result);
1083 struct addrinfo* addr = input;
1089 while (addr && (addr->ai_family != AF_INET6))
1090 addr = addr->ai_next;
1102 const int family = (IPvX == 4) ? AF_INET : AF_INET6;
1103 while (addr && (addr->ai_family != family))
1104 addr = addr->ai_next;
1120 freerdp_set_last_error_if_not(context, errorCode);
1121 freeaddrinfo(input);
1125 int freerdp_tcp_default_connect(rdpContext* context, rdpSettings* settings,
const char* hostname,
1126 int port, DWORD timeout)
1130 socklen_t optlen = 0;
1131 BOOL ipcSocket = FALSE;
1132 BOOL useExternalDefinedSocket = FALSE;
1136 freerdp_set_last_error_if_not(context, FREERDP_ERROR_CONNECT_FAILED);
1141 if (hostname[0] ==
'/')
1144 if (hostname[0] ==
'|')
1145 useExternalDefinedSocket = TRUE;
1147 const char* vsock = utils_is_vsock(hostname);
1150 sockfd = freerdp_uds_connect(hostname);
1154 freerdp_set_last_error_if_not(context, FREERDP_ERROR_CONNECT_FAILED);
1159 else if (useExternalDefinedSocket)
1163 #if defined(HAVE_AF_VSOCK_H)
1165 sockfd = socket(AF_VSOCK, SOCK_STREAM, 0);
1166 struct sockaddr_vm addr = { 0 };
1168 addr.svm_family = AF_VSOCK;
1169 addr.svm_port = port;
1173 unsigned long val = strtoul(hostname, &ptr, 10);
1174 if (errno || (val > UINT32_MAX))
1176 char ebuffer[256] = { 0 };
1177 WLog_ERR(TAG,
"could not extract port from '%s', value=%ul, error=%s", hostname, val,
1178 winpr_strerror(errno, ebuffer,
sizeof(ebuffer)));
1182 if (addr.svm_cid == 2)
1184 addr.svm_flags = VMADDR_FLAG_TO_HOST;
1186 if ((connect(sockfd, (
struct sockaddr*)&addr,
sizeof(
struct sockaddr_vm))) == -1)
1188 WLog_ERR(TAG,
"failed to connect to %s", hostname);
1192 WLog_ERR(TAG,
"Compiled without AF_VSOCK, '%s' not supported", hostname);
1200 if (!settings->GatewayEnabled)
1202 if (!freerdp_tcp_is_hostname_resolvable(context, hostname) ||
1203 settings->RemoteAssistanceMode)
1205 if (settings->TargetNetAddressCount > 0)
1207 WINPR_ASSERT(port <= UINT16_MAX);
1208 sockfd = freerdp_tcp_connect_multi(
1209 context, settings->TargetNetAddresses, settings->TargetNetPorts,
1210 settings->TargetNetAddressCount, (UINT16)port, timeout);
1217 char* peerAddress = NULL;
1218 struct addrinfo* addr = NULL;
1219 struct addrinfo* result = NULL;
1221 result = freerdp_tcp_resolve_host(hostname, port, 0);
1225 freerdp_set_last_error_if_not(context, FREERDP_ERROR_DNS_NAME_NOT_FOUND);
1229 freerdp_set_last_error_log(context, 0);
1237 get_next_addrinfo(context, result, &addr, FREERDP_ERROR_DNS_NAME_NOT_FOUND);
1243 sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
1246 const int lrc = get_next_addrinfo(context, addr->ai_next, &addr,
1247 FREERDP_ERROR_CONNECT_FAILED);
1251 }
while (sockfd < 0);
1253 if ((peerAddress = freerdp_tcp_address_to_string(
1254 (
const struct sockaddr_storage*)addr->ai_addr, NULL)) != NULL)
1256 WLog_DBG(TAG,
"connecting to peer %s", peerAddress);
1260 if (!freerdp_tcp_connect_timeout(context, sockfd, addr->ai_addr, addr->ai_addrlen,
1263 freeaddrinfo(result);
1266 freerdp_set_last_error_if_not(context, FREERDP_ERROR_CONNECT_FAILED);
1268 WLog_ERR(TAG,
"failed to connect to %s", hostname);
1272 freeaddrinfo(result);
1278 free(settings->ClientAddress);
1279 settings->ClientAddress = freerdp_tcp_get_ip_address(sockfd, &settings->IPv6Enabled);
1281 if (!settings->ClientAddress)
1283 if (!useExternalDefinedSocket)
1286 freerdp_set_last_error_if_not(context, FREERDP_ERROR_CONNECT_FAILED);
1288 WLog_ERR(TAG,
"Couldn't get socket ip address");
1294 optlen =
sizeof(optval);
1296 if (!ipcSocket && !useExternalDefinedSocket)
1298 if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (
void*)&optval, optlen) < 0)
1299 WLog_ERR(TAG,
"unable to set TCP_NODELAY");
1303 if (getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, (
void*)&optval, &optlen) == 0)
1305 if (optval < (1024 * 32))
1308 optlen =
sizeof(optval);
1310 if (setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, (
void*)&optval, optlen) < 0)
1314 freerdp_set_last_error_if_not(context, FREERDP_ERROR_CONNECT_FAILED);
1316 WLog_ERR(TAG,
"unable to set receive buffer len");
1322 if (!ipcSocket && !useExternalDefinedSocket)
1324 if (!freerdp_tcp_set_keep_alive_mode(settings, sockfd))
1328 freerdp_set_last_error_if_not(context, FREERDP_ERROR_CONNECT_FAILED);
1330 WLog_ERR(TAG,
"Couldn't set keep alive mode.");
1335 if (WaitForSingleObject(utils_get_abort_event(context->rdp), 0) == WAIT_OBJECT_0)
1344 struct rdp_tcp_layer
1349 typedef struct rdp_tcp_layer rdpTcpLayer;
1351 static int freerdp_tcp_layer_read(
void* userContext,
void* data,
int bytes)
1355 if (!data || !bytes)
1358 rdpTcpLayer* tcpLayer = (rdpTcpLayer*)userContext;
1363 (void)WSAResetEvent(tcpLayer->hEvent);
1364 status = _recv((SOCKET)tcpLayer->sockfd, data, bytes, 0);
1372 error = WSAGetLastError();
1374 if ((error == WSAEWOULDBLOCK) || (error == WSAEINTR) || (error == WSAEINPROGRESS) ||
1375 (error == WSAEALREADY))
1387 static int freerdp_tcp_layer_write(
void* userContext,
const void* data,
int bytes)
1391 if (!data || !bytes)
1394 rdpTcpLayer* tcpLayer = (rdpTcpLayer*)userContext;
1399 status = _send((SOCKET)tcpLayer->sockfd, data, bytes, 0);
1403 error = WSAGetLastError();
1405 if ((error == WSAEWOULDBLOCK) || (error == WSAEINTR) || (error == WSAEINPROGRESS) ||
1406 (error == WSAEALREADY))
1419 static BOOL freerdp_tcp_layer_close(
void* userContext)
1424 rdpTcpLayer* tcpLayer = (rdpTcpLayer*)userContext;
1426 if (tcpLayer->sockfd >= 0)
1427 closesocket((SOCKET)tcpLayer->sockfd);
1428 if (tcpLayer->hEvent)
1429 (void)CloseHandle(tcpLayer->hEvent);
1434 static BOOL freerdp_tcp_layer_wait(
void* userContext, BOOL waitWrite, DWORD timeout)
1439 rdpTcpLayer* tcpLayer = (rdpTcpLayer*)userContext;
1442 int sockfd = tcpLayer->sockfd;
1443 #ifdef WINPR_HAVE_POLL_H
1444 struct pollfd pollset = { 0 };
1445 pollset.fd = sockfd;
1446 pollset.events = waitWrite ? POLLOUT : POLLIN;
1450 status = poll(&pollset, 1, (
int)timeout);
1451 }
while ((status < 0) && (errno == EINTR));
1454 fd_set rset = { 0 };
1455 struct timeval tv = { 0 };
1457 FD_SET(sockfd, &rset);
1461 tv.tv_sec = timeout / 1000;
1462 tv.tv_usec = (timeout % 1000) * 1000;
1468 status = select(sockfd + 1, NULL, &rset, NULL, timeout ? &tv : NULL);
1470 status = select(sockfd + 1, &rset, NULL, NULL, timeout ? &tv : NULL);
1471 }
while ((status < 0) && (errno == EINTR));
1478 static HANDLE freerdp_tcp_layer_get_event(
void* userContext)
1483 rdpTcpLayer* tcpLayer = (rdpTcpLayer*)userContext;
1485 return tcpLayer->hEvent;
1488 rdpTransportLayer* freerdp_tcp_connect_layer(rdpContext* context,
const char* hostname,
int port,
1491 WINPR_ASSERT(context);
1493 const rdpSettings* settings = context->settings;
1494 WINPR_ASSERT(settings);
1497 rdpTcpLayer* tcpLayer = NULL;
1499 int sockfd = freerdp_tcp_connect(context, hostname, port, timeout);
1502 if (!freerdp_tcp_set_keep_alive_mode(settings, sockfd))
1505 layer = transport_layer_new(freerdp_get_transport(context),
sizeof(rdpTcpLayer));
1509 layer->Read = freerdp_tcp_layer_read;
1510 layer->Write = freerdp_tcp_layer_write;
1511 layer->Close = freerdp_tcp_layer_close;
1512 layer->Wait = freerdp_tcp_layer_wait;
1513 layer->GetEvent = freerdp_tcp_layer_get_event;
1515 tcpLayer = (rdpTcpLayer*)layer->userContext;
1516 WINPR_ASSERT(tcpLayer);
1518 tcpLayer->sockfd = -1;
1519 tcpLayer->hEvent = WSACreateEvent();
1520 if (!tcpLayer->hEvent)
1524 if (WSAEventSelect((SOCKET)sockfd, tcpLayer->hEvent, FD_READ | FD_ACCEPT | FD_CLOSE))
1526 WLog_ERR(TAG,
"WSAEventSelect returned 0x%08X", WSAGetLastError());
1530 tcpLayer->sockfd = sockfd;
1536 closesocket((SOCKET)sockfd);
1537 transport_layer_free(layer);
FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.
FREERDP_API BOOL freerdp_settings_get_bool(const rdpSettings *settings, FreeRDP_Settings_Keys_Bool id)
Returns a boolean settings value.
a piece of data in the ring buffer, exactly like a glibc iovec