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

[22427] Fast DDS Auto DS Mode - Feature #5462

Open
wants to merge 4 commits into
base: feature/fastdds-tests/auto_discovery_server
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
10 changes: 7 additions & 3 deletions include/fastdds/rtps/attributes/BuiltinTransports.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,15 @@ inline bool operator ==(
*/
enum class BuiltinTransports : uint16_t
{
NONE = 0, //< No transport will be instantiated
DEFAULT = 1, //< Default value that will instantiate UDPv4 and SHM transports
NONE = 0, //< No transport will be instantiated
DEFAULT = 1, //< Default value that will instantiate UDPv4 and SHM transports
DEFAULTv6 = 2, //< Instantiate UDPv6 and SHM transports
SHM = 3, //< Instantiate SHM transport only
UDPv4 = 4, //< Instantiate UDPv4 transport only
UDPv6 = 5, //< Instantiate UDPv6 transport only
LARGE_DATA = 6, //< Instantiate SHM, UDPv4 and TCPv4 transports, but UDPv4 is only used for bootstrapping discovery
LARGE_DATAv6 = 7 //< Instantiate SHM, UDPv6 and TCPv6 transports, but UDPv6 is only used for bootstrapping discovery
LARGE_DATAv6 = 7, //< Instantiate SHM, UDPv6 and TCPv6 transports, but UDPv6 is only used for bootstrapping discovery
DS_AUTO = 8 //< Instantiate SHM and TCPv4 transports, shall only be used along with ROS_DISCOVERY_SERVER=AUTO
};

inline std::ostream& operator <<(
Expand Down Expand Up @@ -144,6 +145,9 @@ inline std::ostream& operator <<(
case BuiltinTransports::LARGE_DATAv6:
output << "LARGE_DATAv6";
break;
case BuiltinTransports::DS_AUTO:
output << "DS_AUTO";
break;
default:
output << "UNKNOWN";
break;
Expand Down
1 change: 1 addition & 0 deletions resources/xsd/fastdds_profiles.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -1963,6 +1963,7 @@
<xs:enumeration value="UDPv6" />
<xs:enumeration value="LARGE_DATA" />
<xs:enumeration value="LARGE_DATAv6" />
<xs:enumeration value="DS_AUTO" />
</xs:restriction>
</xs:simpleType>

Expand Down
138 changes: 92 additions & 46 deletions src/cpp/rtps/RTPSDomain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#include <rtps/transport/UDPv6Transport.h>
#include <rtps/writer/BaseWriter.hpp>
#include <utils/Host.hpp>
#include <utils/SystemCommandBuilder.hpp>
#include <utils/SystemInfo.hpp>
#include <xmlparser/XMLProfileManager.h>

Expand Down Expand Up @@ -518,59 +519,104 @@ RTPSParticipant* RTPSDomainImpl::clientServerEnvironmentCreationOverride(
// Is up to the caller guarantee the att argument is not modified during the call
RTPSParticipantAttributes client_att(att);

// Retrieve the info from the environment variable
LocatorList_t& server_list = client_att.builtin.discovery_config.m_DiscoveryServers;
if (load_environment_server_info(server_list) && server_list.empty())
{
// It's not an error, the environment variable may not be set. Any issue with environment
// variable syntax is EPROSIMA_LOG_ERROR already
return nullptr;
}
const std::string& ros_discovery_server_env_value = ros_discovery_server_env();

// Check if some address requires the UDPv6, TCPv4 or TCPv6 transport
if (server_list.has_kind<LOCATOR_KIND_UDPv6>() &&
!has_user_transport<fastdds::rtps::UDPv6TransportDescriptor>(client_att))
{
// Extend builtin transports with the UDPv6 transport
auto descriptor = std::make_shared<fastdds::rtps::UDPv6TransportDescriptor>();
descriptor->sendBufferSize = client_att.sendSocketBufferSize;
descriptor->receiveBufferSize = client_att.listenSocketBufferSize;
client_att.userTransports.push_back(std::move(descriptor));
}
if (server_list.has_kind<LOCATOR_KIND_TCPv4>() &&
!has_user_transport<fastdds::rtps::TCPv4TransportDescriptor>(client_att))
if (ros_discovery_server_env_value != "AUTO")
{
// Extend builtin transports with the TCPv4 transport
auto descriptor = std::make_shared<fastdds::rtps::TCPv4TransportDescriptor>();
// Add automatic port
descriptor->add_listener_port(0);
descriptor->sendBufferSize = client_att.sendSocketBufferSize;
descriptor->receiveBufferSize = client_att.listenSocketBufferSize;
client_att.userTransports.push_back(std::move(descriptor));
}
if (server_list.has_kind<LOCATOR_KIND_TCPv6>() &&
!has_user_transport<fastdds::rtps::TCPv6TransportDescriptor>(client_att))
{
// Extend builtin transports with the TCPv6 transport
auto descriptor = std::make_shared<fastdds::rtps::TCPv6TransportDescriptor>();
// Add automatic port
descriptor->add_listener_port(0);
descriptor->sendBufferSize = client_att.sendSocketBufferSize;
descriptor->receiveBufferSize = client_att.listenSocketBufferSize;
client_att.userTransports.push_back(std::move(descriptor));
}
// Retrieve the info from the environment variable
LocatorList_t& server_list = client_att.builtin.discovery_config.m_DiscoveryServers;
if (load_environment_server_info(server_list) && server_list.empty())
{
// It's not an error, the environment variable may not be set. Any issue with environment
// variable syntax is EPROSIMA_LOG_ERROR already
return nullptr;
}

EPROSIMA_LOG_INFO(DOMAIN, "Detected auto client-server environment variable."
<< "Trying to create client with the default server setup: "
<< client_att.builtin.discovery_config.m_DiscoveryServers);
// Check if some address requires the UDPv6, TCPv4 or TCPv6 transport
if (server_list.has_kind<LOCATOR_KIND_UDPv6>() &&
!has_user_transport<fastdds::rtps::UDPv6TransportDescriptor>(client_att))
{
// Extend builtin transports with the UDPv6 transport
auto descriptor = std::make_shared<fastdds::rtps::UDPv6TransportDescriptor>();
descriptor->sendBufferSize = client_att.sendSocketBufferSize;
descriptor->receiveBufferSize = client_att.listenSocketBufferSize;
client_att.userTransports.push_back(std::move(descriptor));
}
if (server_list.has_kind<LOCATOR_KIND_TCPv4>() &&
!has_user_transport<fastdds::rtps::TCPv4TransportDescriptor>(client_att))
{
// Extend builtin transports with the TCPv4 transport
auto descriptor = std::make_shared<fastdds::rtps::TCPv4TransportDescriptor>();
// Add automatic port
descriptor->add_listener_port(0);
descriptor->sendBufferSize = client_att.sendSocketBufferSize;
descriptor->receiveBufferSize = client_att.listenSocketBufferSize;
client_att.userTransports.push_back(std::move(descriptor));
}
if (server_list.has_kind<LOCATOR_KIND_TCPv6>() &&
!has_user_transport<fastdds::rtps::TCPv6TransportDescriptor>(client_att))
{
// Extend builtin transports with the TCPv6 transport
auto descriptor = std::make_shared<fastdds::rtps::TCPv6TransportDescriptor>();
// Add automatic port
descriptor->add_listener_port(0);
descriptor->sendBufferSize = client_att.sendSocketBufferSize;
descriptor->receiveBufferSize = client_att.listenSocketBufferSize;
client_att.userTransports.push_back(std::move(descriptor));
}

client_att.builtin.discovery_config.discoveryProtocol = DiscoveryProtocol::CLIENT;
// RemoteServerAttributes already fill in above
EPROSIMA_LOG_INFO(DOMAIN, "Detected auto client-server environment variable."
<< "Trying to create client with the default server setup: "
<< client_att.builtin.discovery_config.m_DiscoveryServers);

// Check if the client must become a super client
if (ros_super_client_env())
client_att.builtin.discovery_config.discoveryProtocol = DiscoveryProtocol::CLIENT;
// RemoteServerAttributes already fill in above

// Check if the client must become a super client
if (ros_super_client_env())
{
client_att.builtin.discovery_config.discoveryProtocol = DiscoveryProtocol::SUPER_CLIENT;
}
}
else
{
// SUPER_CLIENT
client_att.builtin.discovery_config.discoveryProtocol = DiscoveryProtocol::SUPER_CLIENT;

// DS_AUTO transport. Similar to LARGE_DATA, but without UDPv4
client_att.useBuiltinTransports = false;
client_att.setup_transports(BuiltinTransports::DS_AUTO);

// Ignore initialpeers
client_att.builtin.initialPeersList = LocatorList();

// Add remote DS based on port
eprosima::fastdds::rtps::Locator_t locator;
locator.kind = LOCATOR_KIND_TCPv4;

eprosima::fastdds::rtps::PortParameters port_params;

auto ds_auto_port = port_params.getDiscoveryServerPort(domain_id);

IPLocator::setPhysicalPort(locator, ds_auto_port);
IPLocator::setLogicalPort(locator, ds_auto_port);
IPLocator::setIPv4(locator, 127, 0, 0, 1);

// Point to the well known DS port in the corresponding domain
client_att.builtin.discovery_config.m_DiscoveryServers.push_back(locator);

SystemCommandBuilder sys_command;
int res = sys_command.executable(FAST_DDS_DEFAULT_CLI_SCRIPT_NAME)
.verb(FAST_DDS_DEFAULT_CLI_DISCOVERY_VERB)
.verb(FAST_DDS_DEFAULT_CLI_AUTO_VERB)
.arg("-d")
.value(std::to_string(domain_id))
.build_and_call();
if (res != 0)
{
EPROSIMA_LOG_ERROR(DOMAIN, "Auto discovery server client setup. Unable to spawn daemon.");
return nullptr;
}
}

RTPSParticipant* part = createParticipant(domain_id, enabled, client_att, listen);
Expand Down
28 changes: 28 additions & 0 deletions src/cpp/rtps/attributes/RTPSParticipantAttributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,28 @@ static void setup_transports_large_datav6(
}
}

static void setup_transports_ds_auto(
RTPSParticipantAttributes& att,
bool intraprocess_only,
const fastdds::rtps::BuiltinTransportsOptions& options)
{
if (!intraprocess_only)
{
setup_large_data_shm_transport(att, options);

auto tcp_transport = create_tcpv4_transport(att, options);
att.userTransports.push_back(tcp_transport);

Locator_t tcp_loc;
tcp_loc.kind = LOCATOR_KIND_TCPv4;
IPLocator::setIPv4(tcp_loc, "0.0.0.0");
IPLocator::setPhysicalPort(tcp_loc, 0);
IPLocator::setLogicalPort(tcp_loc, 0);
att.builtin.metatrafficUnicastLocatorList.push_back(tcp_loc);
att.defaultUnicastLocatorList.push_back(tcp_loc);
}
}

void RTPSParticipantAttributes::setup_transports(
fastdds::rtps::BuiltinTransports transports,
const fastdds::rtps::BuiltinTransportsOptions& options)
Expand Down Expand Up @@ -358,6 +380,12 @@ void RTPSParticipantAttributes::setup_transports(
setup_transports_large_datav6(*this, intraprocess_only, options);
break;

case fastdds::rtps::BuiltinTransports::DS_AUTO:
// This parameter will allow allow the initialization of UDP transports with maxMessageSize > 65500 KB (s_maximumMessageSize)
max_msg_size_no_frag = options.maxMessageSize;
setup_transports_ds_auto(*this, intraprocess_only, options);
break;

default:
EPROSIMA_LOG_ERROR(RTPS_PARTICIPANT,
"Setup for '" << transports << "' transport configuration not yet supported.");
Expand Down
6 changes: 3 additions & 3 deletions src/cpp/rtps/attributes/ServerAttributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ bool ros_super_client_env()

const std::string& ros_discovery_server_env()
{
static std::string servers;
SystemInfo::get_env(DEFAULT_ROS2_MASTER_URI, servers);
return servers;
static std::string value;
SystemInfo::get_env(DEFAULT_ROS2_MASTER_URI, value);
return value;
}

bool load_environment_server_info(
Expand Down
16 changes: 9 additions & 7 deletions src/cpp/rtps/attributes/ServerAttributes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,13 +136,15 @@ std::basic_ostream<charT>& operator <<(
// Default server base guidPrefix
const char* const DEFAULT_ROS2_SERVER_GUIDPREFIX = "44.53.00.5f.45.50.52.4f.53.49.4d.41";

/* Environment variable to specify a semicolon-separated list of locators ([transport]ip:port) that define remote server
* locators. The [transport] specification is optional. The default transport is UDPv4.
* For the variable to take any effect, the following pre-condition must be met:
* - The discovery protocol must be either SIMPLE or SERVER.
* a. In the case of SIMPLE, the participant is created as a CLIENT instead.
* b. In the case of SERVER, the participant is created as a SERVER, using the DEFAULT_ROS2_MASTER_URI list to
* expand the list of remote servers.
/* Environment variable that can either serve to:
* - Specify the Discovery Server auto mode by setting its value to AUTO.
* - Specify a semicolon-separated list of locators ([transport]ip:port) that define remote server
* locators. The [transport] specification is optional. The default transport is UDPv4.
* For the variable to take any effect, the following pre-condition must be met:
* - The discovery protocol must be either SIMPLE or SERVER.
* a. In the case of SIMPLE, the participant is created as a CLIENT instead.
* b. In the case of SERVER, the participant is created as a SERVER, using the DEFAULT_ROS2_MASTER_URI list to
* expand the list of remote servers.
*/
const char* const DEFAULT_ROS2_MASTER_URI = "ROS_DISCOVERY_SERVER";

Expand Down
16 changes: 9 additions & 7 deletions src/cpp/rtps/builtin/discovery/participant/PDPServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,19 @@ PDPServer::PDPServer(
// Add remote servers from environment variable
LocatorList_t env_servers;
{
std::lock_guard<std::recursive_mutex> lock(*getMutex());

if (load_environment_server_info(env_servers))
if (ros_discovery_server_env() != "AUTO")
{
for (auto server : env_servers)
std::lock_guard<std::recursive_mutex> lock(*getMutex());
if (load_environment_server_info(env_servers))
{
for (auto server : env_servers)
{
std::unique_lock<eprosima::shared_mutex> disc_lock(mp_builtin->getDiscoveryMutex());
mp_builtin->m_DiscoveryServers.push_back(server);
{
std::unique_lock<eprosima::shared_mutex> disc_lock(mp_builtin->getDiscoveryMutex());
mp_builtin->m_DiscoveryServers.push_back(server);
}
m_discovery.discovery_config.m_DiscoveryServers.push_back(server);
}
m_discovery.discovery_config.m_DiscoveryServers.push_back(server);
}
}
}
Expand Down
6 changes: 4 additions & 2 deletions src/cpp/rtps/participant/RTPSParticipantImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ static void set_builtin_transports_from_env_var(
"UDPv4", BuiltinTransports::UDPv4,
"UDPv6", BuiltinTransports::UDPv6,
"LARGE_DATA", BuiltinTransports::LARGE_DATA,
"LARGE_DATAv6", BuiltinTransports::LARGE_DATAv6))
"LARGE_DATAv6", BuiltinTransports::LARGE_DATAv6,
"DS_AUTO", BuiltinTransports::DS_AUTO))
{
EPROSIMA_LOG_ERROR(RTPS_PARTICIPANT, "Wrong value '" << env_value << "' for environment variable '" <<
env_var_name << "'. Leaving as DEFAULT");
Expand All @@ -140,7 +141,8 @@ static void set_builtin_transports_from_env_var(
"UDPv4", BuiltinTransports::UDPv4,
"UDPv6", BuiltinTransports::UDPv6,
"LARGE_DATA", BuiltinTransports::LARGE_DATA,
"LARGE_DATAv6", BuiltinTransports::LARGE_DATAv6))
"LARGE_DATAv6", BuiltinTransports::LARGE_DATAv6,
"DS_AUTO", BuiltinTransports::DS_AUTO))
{
EPROSIMA_LOG_ERROR(RTPS_PARTICIPANT, "Wrong value '" << env_value << "' for environment variable '" <<
env_var_name << "'. Leaving as DEFAULT");
Expand Down
Loading
Loading