Try next DNS entry on connect failure
Resolves: RHEL-113722
This commit is contained in:
parent
8730c65986
commit
e95c7d895e
55
core-tcp-Don-t-ignore-connect-errors.patch
Normal file
55
core-tcp-Don-t-ignore-connect-errors.patch
Normal file
@ -0,0 +1,55 @@
|
||||
From c3673aaa5b65e8670c218bdfb5916a4112b628c7 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Holy <oholy@redhat.com>
|
||||
Date: Wed, 14 Jan 2026 13:29:34 +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 | 18 ++++++++++++++----
|
||||
1 file changed, 14 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libfreerdp/core/tcp.c b/libfreerdp/core/tcp.c
|
||||
index 1d7eda92e..8a731f117 100644
|
||||
--- a/libfreerdp/core/tcp.c
|
||||
+++ b/libfreerdp/core/tcp.c
|
||||
@@ -26,8 +26,11 @@
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
+#include <inttypes.h>
|
||||
+
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/platform.h>
|
||||
+#include <winpr/string.h>
|
||||
#include <winpr/winsock.h>
|
||||
|
||||
#if !defined(_WIN32)
|
||||
@@ -846,12 +849,19 @@ static BOOL freerdp_tcp_connect_timeout(rdpContext* context, int sockfd, struct
|
||||
if (WAIT_OBJECT_0 != status)
|
||||
goto fail;
|
||||
|
||||
- status = recv(sockfd, NULL, 0, 0);
|
||||
-
|
||||
- if (status == 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 462b02de4107845ab235e1668f78a43a31eb11fc Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Holy <oholy@redhat.com>
|
||||
Date: Wed, 14 Jan 2026 13:38:42 +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 8a731f117..3cf24c160 100644
|
||||
--- a/libfreerdp/core/tcp.c
|
||||
+++ b/libfreerdp/core/tcp.c
|
||||
@@ -1064,6 +1064,53 @@ static BOOL freerdp_tcp_set_keep_alive_mode(const rdpSettings* settings, int soc
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+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)
|
||||
{
|
||||
@@ -1074,14 +1121,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;
|
||||
- }
|
||||
-
|
||||
*result = addr;
|
||||
return 0;
|
||||
|
||||
@@ -1161,9 +1200,11 @@ int freerdp_tcp_connect(rdpContext* context, rdpSettings* settings, const char*
|
||||
freerdp_set_last_error_log(context, 0);
|
||||
|
||||
/*
|
||||
- * 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 051218feec6c3404e625637c9d812817b7d69c26 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Holy <oholy@redhat.com>
|
||||
Date: Wed, 14 Jan 2026 13:28:18 +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 efc2aec36..1d7eda92e 100644
|
||||
--- a/libfreerdp/core/tcp.c
|
||||
+++ b/libfreerdp/core/tcp.c
|
||||
@@ -1162,34 +1162,37 @@ int freerdp_tcp_connect(rdpContext* context, rdpSettings* settings, const char*
|
||||
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 rc = get_next_addrinfo(context, addr->ai_next, &addr,
|
||||
FREERDP_ERROR_CONNECT_FAILED);
|
||||
if (rc < 0)
|
||||
+ {
|
||||
+ freeaddrinfo(result);
|
||||
+ freerdp_set_last_error_if_not(context, FREERDP_ERROR_CONNECT_FAILED);
|
||||
+ WLog_ERR(TAG, "failed to connect to %s", hostname);
|
||||
return rc;
|
||||
+ }
|
||||
}
|
||||
} 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 c13c873fcd3e95dcb21e5a811ac878c21ce38d80 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Holy <oholy@redhat.com>
|
||||
Date: Wed, 14 Jan 2026 13:39:04 +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 3cf24c160..25632f882 100644
|
||||
--- a/libfreerdp/core/tcp.c
|
||||
+++ b/libfreerdp/core/tcp.c
|
||||
@@ -1126,7 +1126,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;
|
||||
}
|
||||
|
||||
@@ -1208,7 +1208,10 @@ int freerdp_tcp_connect(rdpContext* context, rdpSettings* settings, const char*
|
||||
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
|
||||
|
||||
100
core-tcp-retry-all-DNS-entries-until-success.patch
Normal file
100
core-tcp-retry-all-DNS-entries-until-success.patch
Normal file
@ -0,0 +1,100 @@
|
||||
From 84f0e60c998d7c497d141492f7933bc940f7b239 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Holy <oholy@redhat.com>
|
||||
Date: Tue, 6 Jan 2026 12:38:34 +0100
|
||||
Subject: [PATCH] [core,tcp] retry all DNS entries until success
|
||||
|
||||
Backport of commit 4286a4c16495916fbfa6b8a6764c35fc82e1c5ba.
|
||||
|
||||
Co-Authored-By: Claude <noreply@anthropic.com>
|
||||
---
|
||||
libfreerdp/core/tcp.c | 63 +++++++++++++++++++++++++++++--------------
|
||||
1 file changed, 43 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/libfreerdp/core/tcp.c b/libfreerdp/core/tcp.c
|
||||
index 0d0641b82..efc2aec36 100644
|
||||
--- a/libfreerdp/core/tcp.c
|
||||
+++ b/libfreerdp/core/tcp.c
|
||||
@@ -1054,6 +1054,33 @@ static BOOL freerdp_tcp_set_keep_alive_mode(const rdpSettings* settings, int soc
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+static int get_next_addrinfo(rdpContext* context, struct addrinfo* input, struct addrinfo** result,
|
||||
+ UINT32 errorCode)
|
||||
+{
|
||||
+ WINPR_ASSERT(context);
|
||||
+ WINPR_ASSERT(result);
|
||||
+
|
||||
+ struct addrinfo* addr = input;
|
||||
+ 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;
|
||||
+ }
|
||||
+
|
||||
+ *result = addr;
|
||||
+ return 0;
|
||||
+
|
||||
+fail:
|
||||
+ freerdp_set_last_error_if_not(context, errorCode);
|
||||
+ freeaddrinfo(input);
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
int freerdp_tcp_connect(rdpContext* context, rdpSettings* settings, const char* hostname, int port,
|
||||
DWORD timeout)
|
||||
{
|
||||
@@ -1123,30 +1150,26 @@ int freerdp_tcp_connect(rdpContext* context, rdpSettings* settings, const char*
|
||||
}
|
||||
freerdp_set_last_error_log(context, 0);
|
||||
|
||||
- addr = result;
|
||||
+ /*
|
||||
+ * If PreferIPv6OverIPv4 = TRUE we force to IPv6 if there
|
||||
+ * is such an address available, but fall back to first if not found
|
||||
+ */
|
||||
+ const int rc =
|
||||
+ get_next_addrinfo(context, result, &addr, FREERDP_ERROR_DNS_NAME_NOT_FOUND);
|
||||
+ if (rc < 0)
|
||||
+ return rc;
|
||||
|
||||
- if ((addr->ai_family == AF_INET6) && (addr->ai_next != 0) &&
|
||||
- !settings->PreferIPv6OverIPv4)
|
||||
+ do
|
||||
{
|
||||
- while ((addr = addr->ai_next))
|
||||
+ sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
|
||||
+ if (sockfd < 0)
|
||||
{
|
||||
- if (addr->ai_family == AF_INET)
|
||||
- break;
|
||||
+ const int rc = get_next_addrinfo(context, addr->ai_next, &addr,
|
||||
+ FREERDP_ERROR_CONNECT_FAILED);
|
||||
+ if (rc < 0)
|
||||
+ return rc;
|
||||
}
|
||||
-
|
||||
- if (!addr)
|
||||
- addr = result;
|
||||
- }
|
||||
-
|
||||
- sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
|
||||
-
|
||||
- if (sockfd < 0)
|
||||
- {
|
||||
- freerdp_set_last_error_if_not(context, FREERDP_ERROR_CONNECT_FAILED);
|
||||
-
|
||||
- freeaddrinfo(result);
|
||||
- return -1;
|
||||
- }
|
||||
+ } while (sockfd < 0);
|
||||
|
||||
if ((peerAddress = freerdp_tcp_address_to_string(
|
||||
(const struct sockaddr_storage*)addr->ai_addr, NULL)) != NULL)
|
||||
--
|
||||
2.52.0
|
||||
|
||||
13
freerdp.spec
13
freerdp.spec
@ -27,7 +27,7 @@
|
||||
|
||||
Name: freerdp
|
||||
Version: 2.11.7
|
||||
Release: 1%{?dist}
|
||||
Release: 2%{?dist}
|
||||
Epoch: 2
|
||||
Summary: Free implementation of the Remote Desktop Protocol (RDP)
|
||||
License: ASL 2.0
|
||||
@ -35,6 +35,13 @@ URL: http://www.freerdp.com/
|
||||
|
||||
Source0: https://github.com/FreeRDP/FreeRDP/archive/%{version}/FreeRDP-%{version}.tar.gz
|
||||
|
||||
# https://issues.redhat.com/browse/RHEL-113722
|
||||
Patch: core-tcp-retry-all-DNS-entries-until-success.patch
|
||||
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
|
||||
@ -292,6 +299,10 @@ find %{buildroot} -name "*.a" -delete
|
||||
%{_libdir}/pkgconfig/winpr-tools2.pc
|
||||
|
||||
%changelog
|
||||
* Fri Jan 16 2026 Ondrej Holy <oholy@redhat.com> - 2:2.11.7-2
|
||||
- Try next DNS entry on connect failure
|
||||
Resolves: RHEL-113722
|
||||
|
||||
* Thu May 09 2024 Ondrej Holy <oholy@redhat.com> - 2:2.11.7-1
|
||||
- Update to 2.11.7 (CVE-2024-32039, CVE-2024-32040, CVE-2024-32041,
|
||||
CVE-2024-32458, CVE-2024-32459, CVE-2024-32460, CVE-2024-32658,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user