Try next DNS entry on connect failure
Resolves: RHEL-140099
This commit is contained in:
parent
6f098d9bcc
commit
f4bdce6aba
43
core-tcp-Don-t-ignore-connect-errors.patch
Normal file
43
core-tcp-Don-t-ignore-connect-errors.patch
Normal file
@ -0,0 +1,43 @@
|
||||
From 5a856bef31bdbecbaf69bd671d23add9779debd9 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Holy <oholy@redhat.com>
|
||||
Date: Wed, 14 Jan 2026 11:37:16 +0100
|
||||
Subject: [PATCH] [core,tcp] Don't ignore connect errors
|
||||
|
||||
Backport of commit 0bdd8da0993231216a7bb4d5e6e33e47d817a944.
|
||||
|
||||
Co-Authored-By: Claude <noreply@anthropic.com>
|
||||
---
|
||||
libfreerdp/core/tcp.c | 15 +++++++++++----
|
||||
1 file changed, 11 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libfreerdp/core/tcp.c b/libfreerdp/core/tcp.c
|
||||
index 8e7ee20bd..6edfb6d71 100644
|
||||
--- a/libfreerdp/core/tcp.c
|
||||
+++ b/libfreerdp/core/tcp.c
|
||||
@@ -857,12 +857,19 @@ static BOOL freerdp_tcp_connect_timeout(rdpContext* context, int sockfd, struct
|
||||
if (WAIT_OBJECT_0 != status)
|
||||
goto fail;
|
||||
|
||||
- const SSIZE_T res = recv(sockfd, NULL, 0, 0);
|
||||
-
|
||||
- if (res == SOCKET_ERROR)
|
||||
{
|
||||
- if (WSAGetLastError() == WSAECONNRESET)
|
||||
+ INT32 optval = 0;
|
||||
+ socklen_t optlen = sizeof(optval);
|
||||
+ if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval, &optlen) < 0)
|
||||
+ goto fail;
|
||||
+
|
||||
+ if (optval != 0)
|
||||
+ {
|
||||
+ char ebuffer[256] = { 0 };
|
||||
+ WLog_DBG(TAG, "connect failed with error: %s [%" PRId32 "]",
|
||||
+ winpr_strerror(optval, ebuffer, sizeof(ebuffer)), optval);
|
||||
goto fail;
|
||||
+ }
|
||||
}
|
||||
|
||||
status = WSAEventSelect(sockfd, handles[0], 0);
|
||||
--
|
||||
2.52.0
|
||||
|
||||
102
core-tcp-Fix-PreferIPv6OverIPv4-fallback-to-IPv4-add.patch
Normal file
102
core-tcp-Fix-PreferIPv6OverIPv4-fallback-to-IPv4-add.patch
Normal file
@ -0,0 +1,102 @@
|
||||
From 4864954a384e4028298e95a19795505f688b21ae Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Holy <oholy@redhat.com>
|
||||
Date: Wed, 14 Jan 2026 11:38:11 +0100
|
||||
Subject: [PATCH] [core,tcp] Fix PreferIPv6OverIPv4 fallback to IPv4 addresses
|
||||
|
||||
Backport of commit 0bdd8da0993231216a7bb4d5e6e33e47d817a944.
|
||||
|
||||
Co-Authored-By: Claude <noreply@anthropic.com>
|
||||
---
|
||||
libfreerdp/core/tcp.c | 61 ++++++++++++++++++++++++++++++++++++-------
|
||||
1 file changed, 51 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/libfreerdp/core/tcp.c b/libfreerdp/core/tcp.c
|
||||
index 6edfb6d71..83cc9af1e 100644
|
||||
--- a/libfreerdp/core/tcp.c
|
||||
+++ b/libfreerdp/core/tcp.c
|
||||
@@ -1081,6 +1081,53 @@ int freerdp_tcp_connect(rdpContext* context, const char* hostname, int port, DWO
|
||||
return transport_tcp_connect(context->rdp->transport, hostname, port, timeout);
|
||||
}
|
||||
|
||||
+static struct addrinfo* reorder_addrinfo_by_preference(rdpContext* context, struct addrinfo* addr)
|
||||
+{
|
||||
+ WINPR_ASSERT(context);
|
||||
+ WINPR_ASSERT(addr);
|
||||
+
|
||||
+ const BOOL preferIPv6 =
|
||||
+ freerdp_settings_get_bool(context->settings, FreeRDP_PreferIPv6OverIPv4);
|
||||
+ if (!preferIPv6)
|
||||
+ return addr;
|
||||
+
|
||||
+ struct addrinfo* ipv6Head = NULL;
|
||||
+ struct addrinfo* ipv6Tail = NULL;
|
||||
+ struct addrinfo* otherHead = NULL;
|
||||
+ struct addrinfo* otherTail = NULL;
|
||||
+
|
||||
+ /* Partition the list into IPv6 and other addresses */
|
||||
+ while (addr)
|
||||
+ {
|
||||
+ struct addrinfo* next = addr->ai_next;
|
||||
+ addr->ai_next = NULL;
|
||||
+
|
||||
+ if (addr->ai_family == AF_INET6)
|
||||
+ {
|
||||
+ if (!ipv6Head)
|
||||
+ ipv6Head = addr;
|
||||
+ else
|
||||
+ ipv6Tail->ai_next = addr;
|
||||
+ ipv6Tail = addr;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if (!otherHead)
|
||||
+ otherHead = addr;
|
||||
+ else
|
||||
+ otherTail->ai_next = addr;
|
||||
+ otherTail = addr;
|
||||
+ }
|
||||
+ addr = next;
|
||||
+ }
|
||||
+
|
||||
+ /* Concatenate the lists */
|
||||
+ if (ipv6Tail)
|
||||
+ ipv6Tail->ai_next = otherHead;
|
||||
+
|
||||
+ return ipv6Head ? ipv6Head : otherHead;
|
||||
+}
|
||||
+
|
||||
static int get_next_addrinfo(rdpContext* context, struct addrinfo* input, struct addrinfo** result,
|
||||
UINT32 errorCode)
|
||||
{
|
||||
@@ -1091,14 +1138,6 @@ static int get_next_addrinfo(rdpContext* context, struct addrinfo* input, struct
|
||||
if (!addr)
|
||||
goto fail;
|
||||
|
||||
- if (freerdp_settings_get_bool(context->settings, FreeRDP_PreferIPv6OverIPv4))
|
||||
- {
|
||||
- while (addr && (addr->ai_family != AF_INET6))
|
||||
- addr = addr->ai_next;
|
||||
- if (!addr)
|
||||
- addr = input;
|
||||
- }
|
||||
-
|
||||
/* We want to force IPvX, abort if not detected */
|
||||
const UINT32 IPvX = freerdp_settings_get_uint32(context->settings, FreeRDP_ForceIPvX);
|
||||
switch (IPvX)
|
||||
@@ -1237,9 +1276,11 @@ int freerdp_tcp_default_connect(rdpContext* context, rdpSettings* settings, cons
|
||||
|
||||
/* By default we take the first returned entry.
|
||||
*
|
||||
- * If PreferIPv6OverIPv4 = TRUE we force to IPv6 if there
|
||||
- * is such an address available, but fall back to first if not found
|
||||
+ * If PreferIPv6OverIPv4 = TRUE we reorder addresses by preference:
|
||||
+ * IPv6 addresses come first, then other addresses.
|
||||
*/
|
||||
+ result = reorder_addrinfo_by_preference(context, result);
|
||||
+
|
||||
const int rc =
|
||||
get_next_addrinfo(context, result, &addr, FREERDP_ERROR_DNS_NAME_NOT_FOUND);
|
||||
if (rc < 0)
|
||||
--
|
||||
2.52.0
|
||||
|
||||
76
core-tcp-Try-next-DNS-entry-on-connect-failure.patch
Normal file
76
core-tcp-Try-next-DNS-entry-on-connect-failure.patch
Normal file
@ -0,0 +1,76 @@
|
||||
From e4adf227177fd807f47f8621a5e2568748619a23 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Holy <oholy@redhat.com>
|
||||
Date: Wed, 14 Jan 2026 11:34:53 +0100
|
||||
Subject: [PATCH] [core,tcp] Try next DNS entry on connect failure
|
||||
|
||||
Backport of commit bd67348eb3380a66b544835346191bd2138a5ba4.
|
||||
|
||||
Co-Authored-By: Claude <noreply@anthropic.com>
|
||||
---
|
||||
libfreerdp/core/tcp.c | 41 ++++++++++++++++++++++-------------------
|
||||
1 file changed, 22 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/libfreerdp/core/tcp.c b/libfreerdp/core/tcp.c
|
||||
index 53e3a412f..8e7ee20bd 100644
|
||||
--- a/libfreerdp/core/tcp.c
|
||||
+++ b/libfreerdp/core/tcp.c
|
||||
@@ -1241,34 +1241,37 @@ int freerdp_tcp_default_connect(rdpContext* context, rdpSettings* settings, cons
|
||||
do
|
||||
{
|
||||
sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
|
||||
+ if (sockfd >= 0)
|
||||
+ {
|
||||
+ if ((peerAddress = freerdp_tcp_address_to_string(
|
||||
+ (const struct sockaddr_storage*)addr->ai_addr, NULL)) != NULL)
|
||||
+ {
|
||||
+ WLog_DBG(TAG, "connecting to peer %s", peerAddress);
|
||||
+ free(peerAddress);
|
||||
+ }
|
||||
+
|
||||
+ if (!freerdp_tcp_connect_timeout(context, sockfd, addr->ai_addr,
|
||||
+ addr->ai_addrlen, timeout))
|
||||
+ {
|
||||
+ close(sockfd);
|
||||
+ sockfd = -1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (sockfd < 0)
|
||||
{
|
||||
const int lrc = get_next_addrinfo(context, addr->ai_next, &addr,
|
||||
FREERDP_ERROR_CONNECT_FAILED);
|
||||
if (lrc < 0)
|
||||
+ {
|
||||
+ freeaddrinfo(result);
|
||||
+ freerdp_set_last_error_if_not(context, FREERDP_ERROR_CONNECT_FAILED);
|
||||
+ WLog_ERR(TAG, "failed to connect to %s", hostname);
|
||||
return lrc;
|
||||
+ }
|
||||
}
|
||||
} while (sockfd < 0);
|
||||
|
||||
- if ((peerAddress = freerdp_tcp_address_to_string(
|
||||
- (const struct sockaddr_storage*)addr->ai_addr, NULL)) != NULL)
|
||||
- {
|
||||
- WLog_DBG(TAG, "connecting to peer %s", peerAddress);
|
||||
- free(peerAddress);
|
||||
- }
|
||||
-
|
||||
- if (!freerdp_tcp_connect_timeout(context, sockfd, addr->ai_addr, addr->ai_addrlen,
|
||||
- timeout))
|
||||
- {
|
||||
- freeaddrinfo(result);
|
||||
- close(sockfd);
|
||||
-
|
||||
- freerdp_set_last_error_if_not(context, FREERDP_ERROR_CONNECT_FAILED);
|
||||
-
|
||||
- WLog_ERR(TAG, "failed to connect to %s", hostname);
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
freeaddrinfo(result);
|
||||
}
|
||||
}
|
||||
--
|
||||
2.52.0
|
||||
|
||||
39
core-tcp-fix-double-free-in-get_next_addrinfo.patch
Normal file
39
core-tcp-fix-double-free-in-get_next_addrinfo.patch
Normal file
@ -0,0 +1,39 @@
|
||||
From 0a660bf3b3cf2660a4fa15bd37d8b8b3d03fbfef Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Holy <oholy@redhat.com>
|
||||
Date: Wed, 14 Jan 2026 12:55:42 +0100
|
||||
Subject: [PATCH] [core,tcp] fix double free in get_next_addrinfo
|
||||
|
||||
Backport of commit 48197426444b7b3587874b5eae175af1113beab8.
|
||||
|
||||
Co-Authored-By: Claude <noreply@anthropic.com>
|
||||
---
|
||||
libfreerdp/core/tcp.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libfreerdp/core/tcp.c b/libfreerdp/core/tcp.c
|
||||
index 83cc9af1e..a3e12d14b 100644
|
||||
--- a/libfreerdp/core/tcp.c
|
||||
+++ b/libfreerdp/core/tcp.c
|
||||
@@ -1164,7 +1164,7 @@ static int get_next_addrinfo(rdpContext* context, struct addrinfo* input, struct
|
||||
|
||||
fail:
|
||||
freerdp_set_last_error_if_not(context, errorCode);
|
||||
- freeaddrinfo(input);
|
||||
+ *result = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1284,7 +1284,10 @@ int freerdp_tcp_default_connect(rdpContext* context, rdpSettings* settings, cons
|
||||
const int rc =
|
||||
get_next_addrinfo(context, result, &addr, FREERDP_ERROR_DNS_NAME_NOT_FOUND);
|
||||
if (rc < 0)
|
||||
+ {
|
||||
+ freeaddrinfo(result);
|
||||
return rc;
|
||||
+ }
|
||||
|
||||
do
|
||||
{
|
||||
--
|
||||
2.52.0
|
||||
|
||||
12
freerdp.spec
12
freerdp.spec
@ -30,7 +30,7 @@
|
||||
Name: freerdp
|
||||
Epoch: 2
|
||||
Version: 3.10.3
|
||||
Release: 6%{?dist}
|
||||
Release: 7%{?dist}
|
||||
Summary: Free implementation of the Remote Desktop Protocol (RDP)
|
||||
|
||||
# The effective license is Apache-2.0 but:
|
||||
@ -59,6 +59,12 @@ Patch4: Limit-minimum-threadpool-size.patch
|
||||
# https://issues.redhat.com/browse/RHEL-73724
|
||||
Patch: core-connection-print-SSL-warnings-after-init.patch
|
||||
|
||||
# https://issues.redhat.com/browse/RHEL-140099
|
||||
Patch: core-tcp-Try-next-DNS-entry-on-connect-failure.patch
|
||||
Patch: core-tcp-Don-t-ignore-connect-errors.patch
|
||||
Patch: core-tcp-Fix-PreferIPv6OverIPv4-fallback-to-IPv4-add.patch
|
||||
Patch: core-tcp-fix-double-free-in-get_next_addrinfo.patch
|
||||
|
||||
BuildRequires: gcc
|
||||
BuildRequires: gcc-c++
|
||||
BuildRequires: alsa-lib-devel
|
||||
@ -382,6 +388,10 @@ find %{buildroot} -name "*.a" -delete
|
||||
%{_libdir}/pkgconfig/winpr-tools3.pc
|
||||
|
||||
%changelog
|
||||
* Fri Jan 16 2026 Ondrej Holy <oholy@redhat.com> - 2:3.10.3-7
|
||||
- Try next DNS entry on connect failure
|
||||
Resolves: RHEL-140099
|
||||
|
||||
* Tue Dec 16 2025 Ondrej Holy <oholy@redhat.com> - 2:3.10.3-6
|
||||
- Fix broken SSL checks and disable runtime checks (RHEL-73724)
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user