Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configure Discovery Server using names [12349] #2140

Merged
merged 8 commits into from
Aug 13, 2021
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 40 additions & 31 deletions src/cpp/rtps/builtin/discovery/participant/PDPClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,25 @@
*
*/

#include <rtps/builtin/discovery/participant/PDPClient.h>

#include <fastdds/dds/log/Log.hpp>
#include <fastdds/rtps/attributes/RTPSParticipantAttributes.h>
#include <fastdds/rtps/builtin/BuiltinProtocols.h>
#include <fastdds/rtps/builtin/discovery/participant/PDPListener.h>
#include <fastdds/rtps/builtin/liveliness/WLP.h>

#include <fastdds/rtps/history/ReaderHistory.h>
#include <fastdds/rtps/history/WriterHistory.h>
#include <fastdds/rtps/participant/RTPSParticipantListener.h>
#include <fastdds/rtps/reader/StatefulReader.h>
#include <fastdds/rtps/writer/StatefulWriter.h>

#include <fastdds/rtps/attributes/RTPSParticipantAttributes.h>

#include <fastdds/rtps/writer/ReaderProxy.h>

#include <fastdds/rtps/history/WriterHistory.h>
#include <fastdds/rtps/history/ReaderHistory.h>

#include <fastdds/rtps/writer/StatefulWriter.h>
#include <fastrtps/utils/TimeConversion.h>

#include <rtps/builtin/discovery/endpoint/EDPClient.h>
#include <rtps/builtin/discovery/participant/DirectMessageSender.hpp>
#include <rtps/participant/RTPSParticipantImpl.h>
#include <fastdds/rtps/builtin/discovery/participant/PDPListener.h>

#include <fastdds/dds/log/Log.hpp>

#include <rtps/builtin/discovery/participant/PDPClient.h>
#include <rtps/builtin/discovery/participant/timedevent/DSClientEvent.h>
#include <rtps/builtin/discovery/endpoint/EDPClient.h>
#include <rtps/participant/RTPSParticipantImpl.h>
#include <utils/SystemInfo.hpp>

using namespace eprosima::fastrtps;

Expand Down Expand Up @@ -629,9 +623,8 @@ const std::string& ros_discovery_server_env()
{
static std::string servers;
{
#pragma warning(suppress:4996)
const char* data = std::getenv(DEFAULT_ROS2_MASTER_URI);
if (nullptr != data)
const char* data;
if (eprosima::ReturnCode_t::RETCODE_OK == SystemInfo::instance().get_env(DEFAULT_ROS2_MASTER_URI, &data))
{
servers = data;
}
Expand All @@ -654,8 +647,10 @@ bool load_environment_server_info(
return false;
}

// parsing ancillary regex
const std::regex ROS2_IPV4_PATTERN(R"(^((?:[0-9]{1,3}\.){3}[0-9]{1,3})?:?(?:(\d+))?$)");
/* Parsing ancillary regex */
// Address should be <letter,numbers,dots>:<number>. We do not need to verify that the first part
// is an IPv4 address, as it is done latter.
const std::regex ROS2_ADDRESS_PATTERN(R"(^([A-Za-z0-9-.]+)?:?(?:(\d+))?$)");
const std::regex ROS2_SERVER_LIST_PATTERN(R"(([^;]*);?)");

try
Expand All @@ -681,16 +676,30 @@ bool load_environment_server_info(
// now we must parse the inner expression
std::smatch mr;
std::string locator(sm);
if (std::regex_match(locator, mr, ROS2_IPV4_PATTERN, std::regex_constants::match_not_null))
if (std::regex_match(locator, mr, ROS2_ADDRESS_PATTERN, std::regex_constants::match_not_null))
{
std::smatch::iterator it = mr.cbegin();

while (++it != mr.cend())
{
if (!IPLocator::setIPv4(server_locator, it->str()))
std::string address = it->str();

// Check whether the address is IPv4
if (!IPLocator::isIPv4(address))
EduPonz marked this conversation as resolved.
Show resolved Hide resolved
{
auto response = rtps::IPLocator::resolveNameDNS(address);

// Add the first valid IPv4 address that we can find
if (response.first.size() > 0)
{
address = response.first.begin()->data();
}
}

if (!IPLocator::setIPv4(server_locator, address))
{
std::stringstream ss;
ss << "Wrong ipv4 address passed into the server's list " << it->str();
ss << "Wrong ipv4 address passed into the server's list " << address;
throw std::invalid_argument(ss.str());
}

Expand All @@ -705,17 +714,17 @@ bool load_environment_server_info(
// reset the locator to default
IPLocator::setPhysicalPort(server_locator, DEFAULT_ROS2_SERVER_PORT);

if ( it->matched)
if (it->matched)
{
// note stoi throws also an invalid_argument
int port = stoi(it->str());

if ( port > std::numeric_limits<uint16_t>::max())
if (port > std::numeric_limits<uint16_t>::max())
{
throw std::out_of_range("Too larget udp port passed into the server's list");
throw std::out_of_range("Too large udp port passed into the server's list");
}

if ( !IPLocator::setPhysicalPort(server_locator, static_cast<uint16_t>(port)))
if (!IPLocator::setPhysicalPort(server_locator, static_cast<uint16_t>(port)))
{
std::stringstream ss;
ss << "Wrong udp port passed into the server's list " << it->str();
Expand All @@ -728,7 +737,7 @@ bool load_environment_server_info(
// add the server to the list
if (!get_server_client_default_guidPrefix(server_id, server_att.guidPrefix))
{
throw std::invalid_argument("The maximum number of default discovery servers have been reached");
throw std::invalid_argument("The maximum number of default discovery servers has been reached");
}

server_att.metatrafficUnicastLocatorList.clear();
Expand Down Expand Up @@ -757,7 +766,7 @@ bool load_environment_server_info(
throw std::invalid_argument("No default server locators were provided.");
}
}
catch ( std::exception& e )
catch (std::exception& e)
{
logError(SERVER_CLIENT_DISCOVERY, e.what());
attributes.clear();
Expand Down
34 changes: 34 additions & 0 deletions src/cpp/rtps/xmlparser/XMLElementParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2729,6 +2729,23 @@ XMLP_ret XMLParser::getXMLLocatorUDPv4(
{
return XMLP_ret::XML_ERROR;
}
// Check whether the address is IPv4
if (!IPLocator::isIPv4(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
{
logError(XMLPARSER,
"DNS server did not return any IPv4 address for: '" << s << "'. Name: " << name);
return XMLP_ret::XML_ERROR;
}
}
IPLocator::setIPv4(locator, s);
}
else
Expand Down Expand Up @@ -2776,6 +2793,23 @@ XMLP_ret XMLParser::getXMLLocatorUDPv6(
{
return XMLP_ret::XML_ERROR;
}
// Check whether the address is IPv6
if (!IPLocator::isIPv6(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
{
logError(XMLPARSER,
"DNS server did not return any IPv6 address for: '" << s << "'. Name: " << name);
return XMLP_ret::XML_ERROR;
}
}
IPLocator::setIPv6(locator, s);
}
else
Expand Down
47 changes: 43 additions & 4 deletions test/blackbox/common/BlackboxTestsDiscovery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1266,18 +1266,57 @@ TEST(Discovery, ServerClientEnvironmentSetUp)
ASSERT_TRUE(load_environment_server_info(text, output));
ASSERT_EQ(output, standard);

// 7. check ignore some servers scenario
// 8. Check that env var cannot specify more than 256 servers
text = ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"
";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"
";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;192.168.36.34:14520";
output.clear();

JLBuenoLopez marked this conversation as resolved.
Show resolved Hide resolved
ASSERT_FALSE(load_environment_server_info(text, output));

// 8. check non-consistent addresses scenario
// 9. Check addresses as dns name
text = "localhost:12345";

output.clear();
standard.clear();

att.clear();
IPLocator::setIPv4(loc, string("127.0.0.1"));
IPLocator::setPhysicalPort(loc, 12345);
att.metatrafficUnicastLocatorList.push_back(loc);
get_server_client_default_guidPrefix(0, att.guidPrefix);
standard.push_back(att);

ASSERT_TRUE(load_environment_server_info(text, output));
ASSERT_EQ(output, standard);

// 10. Check mixed scenario with addresses and dns
text = "192.168.36.34:14520;localhost:12345;172.30.80.1:31090;";

output.clear();
ASSERT_FALSE(load_environment_server_info(text, output));
standard.clear();

}
att.clear();
IPLocator::setIPv4(loc, string("192.168.36.34"));
IPLocator::setPhysicalPort(loc, 14520);
att.metatrafficUnicastLocatorList.push_back(loc);
get_server_client_default_guidPrefix(0, att.guidPrefix);
standard.push_back(att);

att.clear();
IPLocator::setIPv4(loc, string("127.0.0.1"));
IPLocator::setPhysicalPort(loc, 12345);
att.metatrafficUnicastLocatorList.push_back(loc);
get_server_client_default_guidPrefix(1, att.guidPrefix);
standard.push_back(att);

att.clear();
IPLocator::setIPv4(loc, string("172.30.80.1"));
IPLocator::setPhysicalPort(loc, 31090);
att.metatrafficUnicastLocatorList.push_back(loc);
get_server_client_default_guidPrefix(2, att.guidPrefix);
standard.push_back(att);

ASSERT_TRUE(load_environment_server_info(text, output));
JLBuenoLopez marked this conversation as resolved.
Show resolved Hide resolved
ASSERT_EQ(output, standard);
}
10 changes: 8 additions & 2 deletions tools/fds/README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ General options:
-i --server-id Mandatory unique server identifier. Specifies zero based
server position in ROS_DISCOVERY_SERVER environment variable.

-l --ip-address Server interface chosen to listen the clients. Defaults
to any (0.0.0.0)
-l --ip-address IPv4 address chosen to listen the clients. Defaults
to any (0.0.0.0). Instead of an address, a name can
be specified.

-p --port UDP port chosen to listen the clients. Defaults to 11811

Expand Down Expand Up @@ -41,3 +42,8 @@ Examples:

$ fast-discovery-server -i 1 -l 172.30.144.1 -p 12345 -b
EduPonz marked this conversation as resolved.
Show resolved Hide resolved

5. Launch a default server with id 0 (first on ``ROS_DISCOVERY_SERVER``)
listening on localhost with UDP port 14520. Only localhost clients
can reach the server defining as `ROS_DISCOVERY_SERVER=localhost:14520`.

$ fastdds discovery -i 0 -l localhost -p 14520
38 changes: 22 additions & 16 deletions tools/fds/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,25 @@ int main (
{
while ( pOp )
{
// Get next address
std::string address = string(pOp->arg);

// Check whether the address is IPv4
if (!rtps::IPLocator::isIPv4(address))
EduPonz marked this conversation as resolved.
Show resolved Hide resolved
{
auto response = rtps::IPLocator::resolveNameDNS(address);

// Add the first valid IPv4 address that we can find
if (response.first.size() > 0)
{
address = response.first.begin()->data();
}
}

// Update locator address
if (!rtps::IPLocator::setIPv4(locator, string(pOp->arg)))
if (!rtps::IPLocator::setIPv4(locator, address))
{
cout << "Invalid listening locator address specified:" << pOp->arg << endl;
cout << "Invalid listening locator address specified:" << address << endl;
return 1;
}

Expand Down Expand Up @@ -288,35 +303,26 @@ option::ArgStatus Arg::check_server_id(
if (msg)
{
cout << "Option '" << option.name
<< "' is mandatory. Should be a key indentifier between 0 and 255." << endl;
<< "' is mandatory. Should be a key identifier between 0 and 255." << endl;
}

return option::ARG_ILLEGAL;
}

/*static*/
option::ArgStatus Arg::check_server_ipv4(
option::ArgStatus Arg::required(
const option::Option& option,
bool msg)
{
static const std::regex ipv4(R"(^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$)");

// the argument is required
if ( nullptr != option.arg )
if (nullptr != option.arg)
{
// we must check if its a proper ip address
if ( std::regex_match(option.arg, ipv4))
{
return option::ARG_OK;
}
return option::ARG_OK;
}

if (msg)
{
cout << "Option '" << option.name
<< "' should be a proper IPv4 address." << endl;
cout << "Option '" << option << "' requires an argument" << endl;
}

return option::ARG_ILLEGAL;
}

Expand Down
16 changes: 11 additions & 5 deletions tools/fds/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ struct Arg : public option::Arg
const option::Option& option,
bool msg);

static option::ArgStatus check_server_ipv4(
static option::ArgStatus required(
const option::Option& option,
bool msg);

Expand All @@ -56,9 +56,10 @@ const option::Descriptor usage[] = {
" -i \t--server-id Mandatory unique server identifier. Specifies zero based\n"
"\t server position in ROS_DISCOVERY_SERVER environment variable.\n" },

{ IPADDRESS, 0, "l", "ip-address", Arg::check_server_ipv4,
" -l \t--ip-address Server interface chosen to listen the clients. Defaults\n"
"\t to any (0.0.0.0)\n" },
{ IPADDRESS, 0, "l", "ip-address", Arg::required,
" -l \t--ip-address IPv4 address chosen to listen the clients. Defaults\n"
"\t to any (0.0.0.0). Instead of an address, a name can\n"
"\t be specified."},

{ PORT, 0, "p", "port", Arg::check_udp_port,
" -p \t--port UDP port chosen to listen the clients. Defaults to 11811\n" },
Expand Down Expand Up @@ -89,7 +90,12 @@ const option::Descriptor usage[] = {
"\t listening on 172.30.144.1 with UDP port 12345 and provided with a\n"
"\t backup file. If the server crashes it will automatically restore its\n"
"\t previous state when reenacted.\n\n"
"\t$ " FAST_SERVER_BINARY " -i 1 -l 172.30.144.1 -p 12345 -b" },
"\t$ " FAST_SERVER_BINARY " -i 1 -l 172.30.144.1 -p 12345 -b\n\n"
EduPonz marked this conversation as resolved.
Show resolved Hide resolved

"\t5. Launch a default server with id 0 (first on ROS_DISCOVERY_SERVER)\n"
"\t listening on localhost with UDP port 14520. Only localhost clients\n"
"\t can reach the server defining as ROS_DISCOVERY_SERVER=localhost:14520.\n\n"
"\t$ " FAST_SERVER_BINARY " -i 0 -l localhost -p 14520"},

{ 0, 0, 0, 0, 0, 0 }
};
Expand Down