[core,tcp] Improve IPv4 or IPv6 connect

* Fix +ipv6 option, now fall back to IPv4 if no IPv6 entry found
* Add new option ForceIPvX to fail connect if no such entry is found
This commit is contained in:
akallabeth 2024-06-28 08:42:16 +02:00
parent c9aa349c52
commit 562fa8a03d
No known key found for this signature in database
GPG Key ID: A49454A3FC909FD5
7 changed files with 71 additions and 13 deletions

View File

@ -4554,10 +4554,31 @@ static int freerdp_client_settings_parse_command_line_arguments_int(
if (!freerdp_settings_set_bool(settings, FreeRDP_RedirectHomeDrive, enable))
return COMMAND_LINE_ERROR;
}
CommandLineSwitchCase(arg, "ipv4")
{
if (strncmp(arg->Value, "force", 6) == 0)
{
if (!freerdp_settings_set_uint32(settings, FreeRDP_ForceIPvX, 4))
return COMMAND_LINE_ERROR;
}
else
{
if (!freerdp_settings_set_bool(settings, FreeRDP_PreferIPv6OverIPv4, FALSE))
return COMMAND_LINE_ERROR;
}
}
CommandLineSwitchCase(arg, "ipv6")
{
if (!freerdp_settings_set_bool(settings, FreeRDP_PreferIPv6OverIPv4, enable))
return COMMAND_LINE_ERROR;
if (strncmp(arg->Value, "force", 6) == 0)
{
if (!freerdp_settings_set_uint32(settings, FreeRDP_ForceIPvX, 6))
return COMMAND_LINE_ERROR;
}
else
{
if (!freerdp_settings_set_bool(settings, FreeRDP_PreferIPv6OverIPv4, TRUE))
return COMMAND_LINE_ERROR;
}
}
CommandLineSwitchCase(arg, "clipboard")
{

View File

@ -247,7 +247,9 @@ static const COMMAND_LINE_ARGUMENT_A global_cmd_args[] = {
"Print help" },
{ "home-drive", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL,
"Redirect user home as share" },
{ "ipv6", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, "6",
{ "ipv4", COMMAND_LINE_VALUE_OPTIONAL, "[:force]", NULL, NULL, -1, "4",
"Prefer IPv4 AAA record over IPv6 A record" },
{ "ipv6", COMMAND_LINE_VALUE_OPTIONAL, "[:force]", NULL, NULL, -1, "6",
"Prefer IPv6 AAA record over IPv4 A record" },
#if defined(WITH_JPEG)
{ "jpeg", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "JPEG codec support" },

View File

@ -746,7 +746,8 @@ struct rdp_settings
SETTINGS_DEPRECATED(ALIGN64 BOOL RedirectSerialPorts); /* 4672 */
SETTINGS_DEPRECATED(ALIGN64 BOOL RedirectParallelPorts); /* 4673 */
SETTINGS_DEPRECATED(ALIGN64 BOOL PreferIPv6OverIPv4); /* 4674 */
UINT64 padding4800[4800 - 4675]; /* 4675 */
SETTINGS_DEPRECATED(ALIGN64 UINT32 ForceIPvX); /* 4675 */
UINT64 padding4800[4800 - 4676]; /* 4676 */
/**
* Other Redirection

View File

@ -1736,6 +1736,9 @@ UINT32 freerdp_settings_get_uint32(const rdpSettings* settings, FreeRDP_Settings
case FreeRDP_Floatbar:
return settings->Floatbar;
case FreeRDP_ForceIPvX:
return settings->ForceIPvX;
case FreeRDP_FrameAcknowledge:
return settings->FrameAcknowledge;
@ -2169,6 +2172,10 @@ BOOL freerdp_settings_set_uint32(rdpSettings* settings, FreeRDP_Settings_Keys_UI
settings->Floatbar = cnv.c;
break;
case FreeRDP_ForceIPvX:
settings->ForceIPvX = cnv.c;
break;
case FreeRDP_FrameAcknowledge:
settings->FrameAcknowledge = cnv.c;
break;

View File

@ -334,6 +334,7 @@ static const struct settings_str_entry settings_map[] = {
{ FreeRDP_FakeMouseMotionInterval, FREERDP_SETTINGS_TYPE_UINT32,
"FreeRDP_FakeMouseMotionInterval" },
{ FreeRDP_Floatbar, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_Floatbar" },
{ FreeRDP_ForceIPvX, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_ForceIPvX" },
{ FreeRDP_FrameAcknowledge, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_FrameAcknowledge" },
{ FreeRDP_GatewayAcceptedCertLength, FREERDP_SETTINGS_TYPE_UINT32,
"FreeRDP_GatewayAcceptedCertLength" },

View File

@ -1176,21 +1176,46 @@ int freerdp_tcp_default_connect(rdpContext* context, rdpSettings* settings, cons
}
freerdp_set_last_error_log(context, 0);
/* 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
*/
addr = result;
if ((addr->ai_family == AF_INET6) && (addr->ai_next != 0) &&
!settings->PreferIPv6OverIPv4)
if (freerdp_settings_get_bool(settings, FreeRDP_PreferIPv6OverIPv4))
{
while ((addr = addr->ai_next))
{
if (addr->ai_family == AF_INET)
break;
}
while (addr && (addr->ai_family != AF_INET6))
addr = addr->ai_next;
if (!addr)
addr = result;
}
/* We want to force IPvX, abort if not detected */
const UINT32 IPvX = freerdp_settings_get_uint32(settings, FreeRDP_ForceIPvX);
switch (IPvX)
{
case 4:
case 6:
{
const int family = (IPvX == 4) ? AF_INET : AF_INET6;
while (addr && (addr->ai_family != family))
addr = addr->ai_next;
if (!addr)
{
freerdp_set_last_error_if_not(context, FREERDP_ERROR_DNS_NAME_NOT_FOUND);
return -1;
}
}
break;
default:
break;
}
if (!addr)
{
freerdp_set_last_error_if_not(context, FREERDP_ERROR_DNS_NAME_NOT_FOUND);
return -1;
}
sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
if (sockfd < 0)

View File

@ -257,6 +257,7 @@ static const size_t uint32_list_indices[] = {
FreeRDP_ExtEncryptionMethods,
FreeRDP_FakeMouseMotionInterval,
FreeRDP_Floatbar,
FreeRDP_ForceIPvX,
FreeRDP_FrameAcknowledge,
FreeRDP_GatewayAcceptedCertLength,
FreeRDP_GatewayCredentialsSource,