Merge pull request #4547 from andreesteve/gatewayip
Gateway client (RDG) must connect to same IP/server for both channels
This commit is contained in:
commit
d1b4b410fc
@ -1027,8 +1027,10 @@ static BOOL rdg_tls_in_connect(rdpRdg* rdg, const char* hostname, UINT16 port, i
|
||||
BIO* bufferedBio = NULL;
|
||||
rdpSettings* settings = rdg->settings;
|
||||
const char* peerHostname = settings->GatewayHostname;
|
||||
int peerPort = settings->GatewayPort;
|
||||
UINT16 peerPort = settings->GatewayPort;
|
||||
BOOL isProxyConnection = FALSE;
|
||||
int outChannelSocket = 0;
|
||||
char* gatewayAddress = NULL;
|
||||
assert(hostname != NULL);
|
||||
|
||||
if (settings->ProxyType)
|
||||
@ -1037,17 +1039,45 @@ static BOOL rdg_tls_in_connect(rdpRdg* rdg, const char* hostname, UINT16 port, i
|
||||
peerPort = settings->ProxyPort;
|
||||
isProxyConnection = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/**
|
||||
* if settings->GatewayHostname is a name, it may be mapped to more than one
|
||||
* IP address (thus potentially multiple gateway servers) - to avoid openning
|
||||
* the IN channel with one server and the OUT channel with another server
|
||||
* we want to use the same IP when connecting to both IN and OUT channels
|
||||
* below we get the peer ip address in use by the OUT channel and use it
|
||||
* when opening the connection for the IN channel
|
||||
*/
|
||||
BIO_get_socket(rdg->tlsOut->underlying, &outChannelSocket);
|
||||
gatewayAddress = freerdp_tcp_get_peer_address(outChannelSocket);
|
||||
|
||||
if (gatewayAddress == NULL)
|
||||
{
|
||||
WLog_DBG(TAG,
|
||||
"RDG out channel was created but gateway IP couldn't be resolved. Falling back to resolving gateway hostname again for IN channel.");
|
||||
}
|
||||
else
|
||||
{
|
||||
WLog_DBG(TAG, "Gateway hostname %s resolved to IP %s.", peerHostname, gatewayAddress);
|
||||
peerHostname = gatewayAddress;
|
||||
}
|
||||
}
|
||||
|
||||
sockfd = freerdp_tcp_connect(rdg->context, settings, peerHostname,
|
||||
peerPort, timeout);
|
||||
|
||||
if (sockfd < 1)
|
||||
{
|
||||
free(gatewayAddress);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
socketBio = BIO_new(BIO_s_simple_socket());
|
||||
|
||||
if (!socketBio)
|
||||
{
|
||||
free(gatewayAddress);
|
||||
closesocket(sockfd);
|
||||
return FALSE;
|
||||
}
|
||||
@ -1057,6 +1087,7 @@ static BOOL rdg_tls_in_connect(rdpRdg* rdg, const char* hostname, UINT16 port, i
|
||||
|
||||
if (!bufferedBio)
|
||||
{
|
||||
free(gatewayAddress);
|
||||
BIO_free(socketBio);
|
||||
return FALSE;
|
||||
}
|
||||
@ -1066,6 +1097,7 @@ static BOOL rdg_tls_in_connect(rdpRdg* rdg, const char* hostname, UINT16 port, i
|
||||
|
||||
if (!status)
|
||||
{
|
||||
free(gatewayAddress);
|
||||
BIO_free_all(bufferedBio);
|
||||
return FALSE;
|
||||
}
|
||||
@ -1077,6 +1109,7 @@ static BOOL rdg_tls_in_connect(rdpRdg* rdg, const char* hostname, UINT16 port, i
|
||||
|
||||
if (status < 1)
|
||||
{
|
||||
free(gatewayAddress);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -664,17 +664,16 @@ BIO_METHOD* BIO_s_buffered_socket(void)
|
||||
return bio_methods;
|
||||
}
|
||||
|
||||
static char* freerdp_tcp_get_ip_address(int sockfd, BOOL* pIPv6)
|
||||
static char* freerdp_tcp_address_to_string(const struct sockaddr_storage* addr, BOOL* pIPv6)
|
||||
{
|
||||
socklen_t length;
|
||||
char ipAddress[INET6_ADDRSTRLEN + 1] = { 0 };
|
||||
struct sockaddr_storage saddr = { 0 };
|
||||
struct sockaddr_in6* sockaddr_ipv6 = (struct sockaddr_in6*)&saddr;
|
||||
struct sockaddr_in* sockaddr_ipv4 = (struct sockaddr_in*)&saddr;
|
||||
length = sizeof(struct sockaddr_storage);
|
||||
struct sockaddr_in6* sockaddr_ipv6 = (struct sockaddr_in6*)addr;
|
||||
struct sockaddr_in* sockaddr_ipv4 = (struct sockaddr_in*)addr;
|
||||
|
||||
if (getsockname(sockfd, (struct sockaddr*)&saddr, &length) != 0)
|
||||
if (addr == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (sockaddr_ipv4->sin_family)
|
||||
{
|
||||
@ -698,12 +697,40 @@ static char* freerdp_tcp_get_ip_address(int sockfd, BOOL* pIPv6)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pIPv6)
|
||||
if (pIPv6 != NULL)
|
||||
{
|
||||
*pIPv6 = (sockaddr_ipv4->sin_family == AF_INET6);
|
||||
}
|
||||
|
||||
return _strdup(ipAddress);
|
||||
}
|
||||
|
||||
static char* freerdp_tcp_get_ip_address(int sockfd, BOOL* pIPv6)
|
||||
{
|
||||
struct sockaddr_storage saddr = { 0 };
|
||||
socklen_t length = sizeof(struct sockaddr_storage);
|
||||
|
||||
if (getsockname(sockfd, (struct sockaddr*)&saddr, &length) != 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return freerdp_tcp_address_to_string(&saddr, pIPv6);
|
||||
}
|
||||
|
||||
char* freerdp_tcp_get_peer_address(int sockfd)
|
||||
{
|
||||
struct sockaddr_storage saddr = { 0 };
|
||||
socklen_t length = sizeof(struct sockaddr_storage);
|
||||
|
||||
if (getpeername(sockfd, (struct sockaddr*)&saddr, &length) != 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return freerdp_tcp_address_to_string(&saddr, NULL);
|
||||
}
|
||||
|
||||
static int freerdp_uds_connect(const char* path)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
@ -1110,6 +1137,7 @@ int freerdp_tcp_connect(rdpContext* context, rdpSettings* settings,
|
||||
if (sockfd <= 0)
|
||||
{
|
||||
char port_str[16];
|
||||
char* peerAddress;
|
||||
struct addrinfo hints;
|
||||
struct addrinfo* addr;
|
||||
struct addrinfo* result;
|
||||
@ -1150,6 +1178,12 @@ int freerdp_tcp_connect(rdpContext* context, rdpSettings* settings,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((peerAddress = freerdp_tcp_address_to_string(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))
|
||||
{
|
||||
|
@ -67,4 +67,6 @@ FREERDP_LOCAL int freerdp_tcp_connect(rdpContext* context,
|
||||
rdpSettings* settings,
|
||||
const char* hostname, int port, int timeout);
|
||||
|
||||
FREERDP_LOCAL char* freerdp_tcp_get_peer_address(int sockfd);
|
||||
|
||||
#endif /* FREERDP_LIB_CORE_TCP_H */
|
||||
|
Loading…
x
Reference in New Issue
Block a user