Skip to content

Commit

Permalink
Refs #21506. Attempt DNS resolution when setting locator's IP
Browse files Browse the repository at this point in the history
Signed-off-by: Juan Lopez Fernandez <[email protected]>
  • Loading branch information
juanlofer-eprosima committed Nov 27, 2024
1 parent 005191b commit 15dcf2d
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 53 deletions.
113 changes: 95 additions & 18 deletions src/cpp/utils/IPLocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,32 @@ bool IPLocator::setIPv4(
// This function do not set address to 0 in case it fails
// Be careful, do not set all IP to 0 because WAN and LAN could be set beforehand

std::stringstream ss(ipv4);
std::string s(ipv4);
if (!IPLocator::isIPv4(s))
{
// Attempt DNS resolution
auto response = IPLocator::resolveNameDNS(s);

// Add the first valid IPv4 address that we can find
if (response.first.size() > 0)
{
s = response.first.begin()->data();
}
else
{
EPROSIMA_LOG_WARNING(IP_LOCATOR, "IPv4 " << s << " error format. Expected X.X.X.X or valid DNS name");
return false;
}
}

// Redundant check for extra security (here a custom regex is used instead of asio's verification)
if (!IPLocator::isIPv4(s))
{
EPROSIMA_LOG_WARNING(IP_LOCATOR, "Resolved IPv4 " << s << " error format. Expected X.X.X.X");
return false;
}

std::stringstream ss(s);
uint32_t a;
uint32_t b;
uint32_t c;
Expand All @@ -127,7 +152,7 @@ bool IPLocator::setIPv4(
// If there are more info to read, it fails
return ss.rdbuf()->in_avail() == 0;
}
EPROSIMA_LOG_WARNING(IP_LOCATOR, "IPv4 " << ipv4 << " error format. Expected X.X.X.X");
EPROSIMA_LOG_WARNING(IP_LOCATOR, "IPv4 " << s << " error format. Expected X.X.X.X");
return false;
}

Expand Down Expand Up @@ -254,14 +279,34 @@ bool IPLocator::setIPv6(
return false;
}

if (!IPv6isCorrect(ipv6))
std::string s(ipv6);
if (!IPLocator::isIPv6(s))
{
EPROSIMA_LOG_WARNING(IP_LOCATOR, "IPv6 " << ipv6 << " is not well defined");
// Attempt DNS resolution
auto response = IPLocator::resolveNameDNS(s);

// Add the first valid IPv6 address that we can find
if (response.second.size() > 0)
{
s = response.second.begin()->data();
}
else
{
EPROSIMA_LOG_WARNING(IP_LOCATOR,
"IPv6 " << s << " error format. Expected well defined address or valid DNS name");
return false;
}
}

// Redundant check for extra security (here a custom regex is used instead of asio's verification)
if (!IPLocator::isIPv6(s))
{
EPROSIMA_LOG_WARNING(IP_LOCATOR, "Resolved IPv6 " << s << " error format.");
return false;
}

LOCATOR_ADDRESS_INVALID(locator.address);
uint16_t count = (uint16_t) std::count_if( ipv6.begin(), ipv6.end(), []( char c )
uint16_t count = (uint16_t) std::count_if( s.begin(), s.end(), []( char c )
{
return c == ':';
}); // C type cast to avoid Windows warnings
Expand All @@ -274,10 +319,10 @@ bool IPLocator::setIPv6(
size_t aux_prev; // This must be size_t as string::npos could change value depending on size_t size

// Check whether is a zero block and where
if (ipv6.front() == ':')
if (s.front() == ':')
{
// First element equal : -> starts with zeros
if (ipv6.back() == ':')
if (s.back() == ':')
{
// Empty string (correct ipv6 format)
initial_zeros = 16;
Expand All @@ -291,7 +336,7 @@ bool IPLocator::setIPv6(
initial_zeros = (7 - (count - 2)) * 2;
}
}
else if (ipv6.back() == ':')
else if (s.back() == ':')
{
// Last element equal : -> ends with zeros
// It does not start with :: (previous if)
Expand All @@ -300,8 +345,8 @@ bool IPLocator::setIPv6(
else
{
// It does not starts or ends with zeros, but it could have :: in the middle or not have it
aux_prev = ipv6.size(); // Aux could be 1 so this number must be unreacheable
aux = ipv6.find(':'); // Index of first ':'
aux_prev = s.size(); // Aux could be 1 so this number must be unreacheable
aux = s.find(':'); // Index of first ':'

// Look for "::" will loop string twice
// Therefore, we use this loop that will go over less or equal once
Expand All @@ -317,13 +362,13 @@ bool IPLocator::setIPv6(
// Not "::" found, keep searching in next ':'
position_zeros += 2; // It stores the point where the 0 block is
aux_prev = aux;
aux = ipv6.find(':', aux + 1);
aux = s.find(':', aux + 1);
}
}

char punct;
std::stringstream ss;
ss << std::hex << ipv6;
ss << std::hex << s;
uint16_t i;
uint32_t input_aux; // It cannot be uint16_t or we could not find whether the input number is bigger than allowed

Expand All @@ -343,7 +388,7 @@ bool IPLocator::setIPv6(
ss >> punct >> input_aux;
if (input_aux >= 65536)
{
EPROSIMA_LOG_WARNING(IP_LOCATOR, "IPv6 " << ipv6 << " has values higher than expected (65536)");
EPROSIMA_LOG_WARNING(IP_LOCATOR, "IPv6 " << s << " has values higher than expected (65536)");
return false;
}
locator.address[i++] = octet(input_aux >> 8);
Expand All @@ -364,7 +409,7 @@ bool IPLocator::setIPv6(
ss >> input_aux >> punct;
if (input_aux >= 65536)
{
EPROSIMA_LOG_WARNING(IP_LOCATOR, "IPv6 " << ipv6 << " has values higher than expected (65536)");
EPROSIMA_LOG_WARNING(IP_LOCATOR, "IPv6 " << s << " has values higher than expected (65536)");
return false;
}
locator.address[i++] = octet(input_aux >> 8);
Expand All @@ -386,7 +431,7 @@ bool IPLocator::setIPv6(
ss >> input_aux >> punct;
if (input_aux >= 65536)
{
EPROSIMA_LOG_WARNING(IP_LOCATOR, "IPv6 " << ipv6 << " has values higher than expected (65536)");
EPROSIMA_LOG_WARNING(IP_LOCATOR, "IPv6 " << s << " has values higher than expected (65536)");
return false;
}
locator.address[i++] = octet(input_aux >> 8);
Expand All @@ -403,7 +448,7 @@ bool IPLocator::setIPv6(
ss >> punct >> input_aux;
if (input_aux >= 65536)
{
EPROSIMA_LOG_WARNING(IP_LOCATOR, "IPv6 " << ipv6 << " has values higher than expected (65536)");
EPROSIMA_LOG_WARNING(IP_LOCATOR, "IPv6 " << s << " has values higher than expected (65536)");
return false;
}
locator.address[i++] = octet(input_aux >> 8);
Expand All @@ -421,7 +466,7 @@ bool IPLocator::setIPv6(
ss >> punct >> input_aux;
if (input_aux >= 65536)
{
EPROSIMA_LOG_WARNING(IP_LOCATOR, "IPv6 " << ipv6 << " has values higher than expected (65536)");
EPROSIMA_LOG_WARNING(IP_LOCATOR, "IPv6 " << s << " has values higher than expected (65536)");
return false;
}
locator.address[i++] = octet(input_aux >> 8);
Expand Down Expand Up @@ -671,7 +716,38 @@ bool IPLocator::setWan(
Locator_t& locator,
const std::string& wan)
{
std::stringstream ss(wan);
if (locator.kind != LOCATOR_KIND_TCPv4)
{
EPROSIMA_LOG_WARNING(IP_LOCATOR, "Trying to set WAN address in a non TCP-IPv4 Locator");
return false;
}

std::string s(wan);
if (!IPLocator::isIPv4(s))
{
// Attempt DNS resolution
auto response = IPLocator::resolveNameDNS(s);

// Add the first valid IPv4 address that we can find
if (response.first.size() > 0)
{
s = response.first.begin()->data();
}
else
{
EPROSIMA_LOG_WARNING(IP_LOCATOR, "IPv4 " << s << " error format. Expected X.X.X.X or valid DNS name");
return false;
}
}

// Redundant check for extra security (here a custom regex is used instead of asio's verification)
if (!IPLocator::isIPv4(s))
{
EPROSIMA_LOG_WARNING(IP_LOCATOR, "Resolved IPv4 " << s << " error format. Expected X.X.X.X");
return false;
}

std::stringstream ss(s);
int a, b, c, d; //to store the 4 ints
char ch; //to temporarily store the '.'

Expand All @@ -683,6 +759,7 @@ bool IPLocator::setWan(
locator.address[11] = (octet)d;
return true;
}
EPROSIMA_LOG_WARNING(IP_LOCATOR, "IPv4 " << s << " error format. Expected X.X.X.X");
return false;
}

Expand Down
56 changes: 21 additions & 35 deletions src/cpp/xmlparser/XMLElementParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3069,24 +3069,11 @@ XMLP_ret XMLParser::getXMLLocatorUDPv4(
{
return XMLP_ret::XML_ERROR;
}
// Check whether the address is IPv4
if (!IPLocator::isIPv4(s))
if (!IPLocator::setIPv4(locator, s))
{
auto response = rtps::IPLocator::resolveNameDNS(s);

// Add the first valid IPv4 address that we can find
if (response.first.size() > 0)
{
s = response.first.begin()->data();
}
else
{
EPROSIMA_LOG_ERROR(XMLPARSER,
"DNS server did not return any IPv4 address for: '" << s << "'. Name: " << name);
return XMLP_ret::XML_ERROR;
}
EPROSIMA_LOG_ERROR(XMLPARSER, "Failed to parse UDPv4 locator's " << ADDRESS << " tag");
return XMLP_ret::XML_ERROR;
}
IPLocator::setIPv4(locator, s);
}
else
{
Expand Down Expand Up @@ -3142,24 +3129,11 @@ XMLP_ret XMLParser::getXMLLocatorUDPv6(
{
return XMLP_ret::XML_ERROR;
}
// Check whether the address is IPv6
if (!IPLocator::isIPv6(s))
if (!IPLocator::setIPv6(locator, s))
{
auto response = rtps::IPLocator::resolveNameDNS(s);

// Add the first valid IPv6 address that we can find
if (response.second.size() > 0)
{
s = response.second.begin()->data();
}
else
{
EPROSIMA_LOG_ERROR(XMLPARSER,
"DNS server did not return any IPv6 address for: '" << s << "'. Name: " << name);
return XMLP_ret::XML_ERROR;
}
EPROSIMA_LOG_ERROR(XMLPARSER, "Failed to parse UDPv6 locator's " << ADDRESS << " tag");
return XMLP_ret::XML_ERROR;
}
IPLocator::setIPv6(locator, s);
}
else
{
Expand Down Expand Up @@ -3230,7 +3204,11 @@ XMLP_ret XMLParser::getXMLLocatorTCPv4(
{
return XMLP_ret::XML_ERROR;
}
IPLocator::setIPv4(locator, s);
if (!IPLocator::setIPv4(locator, s))
{
EPROSIMA_LOG_ERROR(XMLPARSER, "Failed to parse TCPv4 locator's " << ADDRESS << " tag");
return XMLP_ret::XML_ERROR;
}
}
else if (strcmp(name, WAN_ADDRESS) == 0)
{
Expand All @@ -3240,7 +3218,11 @@ XMLP_ret XMLParser::getXMLLocatorTCPv4(
{
return XMLP_ret::XML_ERROR;
}
IPLocator::setWan(locator, s);
if (!IPLocator::setWan(locator, s))
{
EPROSIMA_LOG_ERROR(XMLPARSER, "Failed to parse TCPv4 locator's " << WAN_ADDRESS << " tag");
return XMLP_ret::XML_ERROR;
}
}
else if (strcmp(name, UNIQUE_LAN_ID) == 0)
{
Expand Down Expand Up @@ -3319,7 +3301,11 @@ XMLP_ret XMLParser::getXMLLocatorTCPv6(
{
return XMLP_ret::XML_ERROR;
}
IPLocator::setIPv6(locator, s);
if (!IPLocator::setIPv6(locator, s))
{
EPROSIMA_LOG_ERROR(XMLPARSER, "Failed to parse TCPv6 locator's " << ADDRESS << " tag");
return XMLP_ret::XML_ERROR;
}
}
else
{
Expand Down

0 comments on commit 15dcf2d

Please sign in to comment.