Merge pull request #4282 from akallabeth/force_ipv6

Fix #4281: Added option to prefer IPv6 over IPv4
This commit is contained in:
David Fort 2017-11-28 10:48:53 +01:00 committed by GitHub
commit cf33966f2e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 48 additions and 23 deletions

View File

@ -119,6 +119,7 @@ static COMMAND_LINE_ARGUMENT_A args[] =
{ "heartbeat", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Support heartbeat PDUs" },
{ "help", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_HELP, NULL, NULL, NULL, -1, "?", "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", "Prefer IPv6 AAA record over IPv4 A record"},
#if defined(WITH_JPEG)
{ "jpeg", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "Enable JPEG codec" },
{ "jpeg-quality", COMMAND_LINE_VALUE_REQUIRED, "<percentage>", NULL, NULL, -1, NULL, "JPEG quality" },
@ -232,12 +233,12 @@ static void freerdp_client_print_command_line_args(COMMAND_LINE_ARGUMENT_A* arg)
|| (arg->Flags & COMMAND_LINE_VALUE_OPTIONAL))
{
BOOL overlong = FALSE;
printf(" %s", "/");
if (arg->Format)
{
size_t length = (strlen(arg->Name) + strlen(arg->Format) + 2);
if (arg->Flags & COMMAND_LINE_VALUE_OPTIONAL)
length += 2;
@ -315,7 +316,6 @@ BOOL freerdp_client_print_command_line_help_ex(int argc, char** argv,
printf("Multimedia Redirection: /multimedia:sys:alsa\n");
printf("USB Device Redirection: /usb:id,dev:054c:0268\n");
printf("\n");
printf("For Gateways, the https_proxy environment variable is respected:\n");
#ifdef _WIN32
printf(" set HTTPS_PROXY=http://proxy.contoso.com:3128/\n");
@ -324,7 +324,6 @@ BOOL freerdp_client_print_command_line_help_ex(int argc, char** argv,
#endif
printf(" xfreerdp /g:rdp.contoso.com ...\n");
printf("\n");
printf("More documentation is coming, in the meantime consult source files\n");
printf("\n");
return TRUE;
@ -348,7 +347,6 @@ static int freerdp_client_command_line_pre_filter(void* context, int index,
if (!(settings->ConnectionFile = _strdup(argv[index])))
return COMMAND_LINE_ERROR_MEMORY;
return 1;
}
}
@ -362,7 +360,6 @@ static int freerdp_client_command_line_pre_filter(void* context, int index,
if (!(settings->AssistanceFile = _strdup(argv[index])))
return COMMAND_LINE_ERROR_MEMORY;
return 1;
}
}
@ -1073,6 +1070,7 @@ BOOL freerdp_parse_hostname(char* hostname, char** host, int* port)
if ((errno != 0) || (val <= 0) || (val > UINT16_MAX))
return FALSE;
*host = (char*) calloc(length + 1UL, sizeof(char));
if (!(*host))
@ -1495,7 +1493,6 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
}
else
{
if (allowUnknown)
{
flags |= COMMAND_LINE_IGN_UNKNOWN_KEYWORD;
@ -1557,6 +1554,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
if ((errno != 0) || (val == 0) || (val > UINT16_MAX))
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
length = (int)(p - arg->Value);
settings->ServerPort = val;
@ -1690,6 +1688,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
settings->PercentScreenUseWidth = 1;
partial = TRUE;
}
if (strchr(p, 'h'))
{
settings->PercentScreenUseHeight = 1;
@ -1952,6 +1951,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
if ((errno != 0) || (val == 0) || (val > UINT16_MAX))
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
length = (int)(p - arg->Value);
settings->GatewayPort = val;
@ -2071,6 +2071,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
long type;
char* pEnd;
type = strtol(arg->Value, &pEnd, 10);
if (errno != 0)
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
@ -2167,6 +2168,10 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
{
settings->RedirectHomeDrive = arg->Value ? TRUE : FALSE;
}
CommandLineSwitchCase(arg, "ipv6")
{
settings->PreferIPv6OverIPv4 = TRUE;
}
CommandLineSwitchCase(arg, "clipboard")
{
settings->RedirectClipboard = arg->Value ? TRUE : FALSE;
@ -2211,6 +2216,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
long type;
char* pEnd;
type = strtol(arg->Value, &pEnd, 10);
if (errno != 0)
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
@ -2277,6 +2283,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
if (arg->Value)
{
#ifdef WITH_GFX_H264
if (_strnicmp("AVC444", arg->Value, 6) == 0)
{
settings->GfxH264 = TRUE;
@ -2295,8 +2302,10 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
CommandLineSwitchCase(arg, "gfx-thin-client")
{
settings->GfxThinClient = arg->Value ? TRUE : FALSE;
if (settings->GfxThinClient)
settings->GfxSmallCache = TRUE;
settings->SupportGraphicsPipeline = TRUE;
}
CommandLineSwitchCase(arg, "gfx-small-cache")
@ -2385,6 +2394,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
if ((errno != 0) || (val > UINT32_MAX))
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
settings->SendPreconnectionPdu = TRUE;
settings->PreconnectionId = val;
}
@ -2453,6 +2463,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
CommandLineSwitchCase(arg, "from-stdin")
{
settings->CredentialsFromStdin = TRUE;
if (arg->Flags & COMMAND_LINE_VALUE_PRESENT)
{
promptForPassword = (strncmp(arg->Value, "force", 6) == 0);
@ -2582,6 +2593,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
{
settings->NSCodec = TRUE;
}
#if defined(WITH_JPEG)
else if (strcmp(arg->Value, "jpeg") == 0)
{
@ -2590,6 +2602,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
if (settings->JpegQuality == 0)
settings->JpegQuality = 75;
}
#endif
}
CommandLineSwitchCase(arg, "fast-path")
@ -3137,6 +3150,7 @@ BOOL freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings)
int count;
count = 1;
p[0] = "echo";
if (!freerdp_client_add_dynamic_channel(settings, count, p))
return FALSE;
}

View File

@ -1394,7 +1394,8 @@ struct rdp_settings
/* Serial and Parallel Port Redirection */
ALIGN64 BOOL RedirectSerialPorts; /* 4672 */
ALIGN64 BOOL RedirectParallelPorts; /* 4673 */
UINT64 padding4800[4800 - 4674]; /* 4674 */
ALIGN64 BOOL PreferIPv6OverIPv4; /* 4674 */
UINT64 padding4800[4800 - 4675]; /* 4675 */
/**
* Other Redirection

View File

@ -664,26 +664,37 @@ BIO_METHOD* BIO_s_buffered_socket(void)
return bio_methods;
}
char* freerdp_tcp_get_ip_address(int sockfd)
static char* freerdp_tcp_get_ip_address(int sockfd, BOOL* pIPv6)
{
BYTE* ip;
socklen_t length;
char ipAddress[32];
char ipAddress[INET6_ADDRSTRLEN + 1];
struct sockaddr_in sockaddr;
length = sizeof(sockaddr);
ZeroMemory(&sockaddr, length);
if (getsockname(sockfd, (struct sockaddr*) &sockaddr, &length) == 0)
if (getsockname(sockfd, (struct sockaddr*) &sockaddr, &length) != 0)
return NULL;
switch (sockaddr.sin_family)
{
ip = (BYTE*)(&sockaddr.sin_addr);
sprintf_s(ipAddress, sizeof(ipAddress), "%"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8"", ip[0], ip[1], ip[2],
ip[3]);
}
else
{
strcpy(ipAddress, "127.0.0.1");
case AF_INET:
case AF_INET6:
if (!inet_ntop(sockaddr.sin_family, &sockaddr.sin_addr, ipAddress, sizeof(ipAddress)))
return NULL;
break;
case AF_UNIX:
strcpy(ipAddress, "127.0.0.1");
break;
default:
return NULL;
}
if (pIPv6)
*pIPv6 = (sockaddr.sin_family == AF_INET6);
return _strdup(ipAddress);
}
@ -813,7 +824,7 @@ static BOOL freerdp_tcp_connect_timeout(rdpContext* context, int sockfd,
}
static int freerdp_tcp_connect_multi(rdpContext* context, char** hostnames,
UINT32* ports, int count, int port,
UINT32* ports, UINT32 count, int port,
int timeout)
{
int index;
@ -992,7 +1003,7 @@ BOOL freerdp_tcp_set_keep_alive_mode(int sockfd)
#endif
#ifndef SOL_TCP
/* "tcp" from /etc/protocols as getprotobyname(3C) */
/* "tcp" from /etc/protocols as getprotobyname(3C) */
#define SOL_TCP 6
#endif
#ifdef TCP_KEEPCNT
@ -1110,7 +1121,7 @@ int freerdp_tcp_connect(rdpContext* context, rdpSettings* settings,
addr = result;
if ((addr->ai_family == AF_INET6) && (addr->ai_next != 0))
if ((addr->ai_family == AF_INET6) && (addr->ai_next != 0) && !settings->PreferIPv6OverIPv4)
{
while ((addr = addr->ai_next))
{
@ -1143,9 +1154,8 @@ int freerdp_tcp_connect(rdpContext* context, rdpSettings* settings,
}
}
settings->IPv6Enabled = FALSE;
free(settings->ClientAddress);
settings->ClientAddress = freerdp_tcp_get_ip_address(sockfd);
settings->ClientAddress = freerdp_tcp_get_ip_address(sockfd, &settings->IPv6Enabled);
if (!settings->ClientAddress)
{