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

switch to local udp broadcast for local network mode (fixes #1191) #1261

Merged
merged 3 commits into from
Nov 21, 2023
Merged
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
7 changes: 4 additions & 3 deletions ecal/core/src/ecal_log_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,17 +145,18 @@ namespace eCAL
m_logfile = fopen(m_logfile_name.c_str(), "w");
}

// create log udp sender
// set network attributes
if(m_filter_mask_udp != 0)
{
SSenderAttr attr;
attr.address = UDP::GetLoggingMulticastAddress();
attr.address = UDP::GetLoggingAddress();
attr.port = UDP::GetLoggingPort();
attr.ttl = UDP::GetMulticastTtl();
attr.broadcast = !Config::IsNetworkEnabled();
attr.loopback = true;
attr.ttl = UDP::GetMulticastTtl();
attr.sndbuf = Config::GetUdpMulticastSndBufSizeBytes();

// create udp logging sender
m_udp_sender = std::make_unique<CUDPSender>(attr);
}

Expand Down
4 changes: 2 additions & 2 deletions ecal/core/src/ecal_registration_provider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,14 @@ namespace eCAL
{
// set network attributes
SSenderAttr attr;
attr.address = UDP::GetRegistrationMulticastAddress();
attr.address = UDP::GetRegistrationAddress();
attr.port = UDP::GetRegistrationPort();
attr.ttl = UDP::GetMulticastTtl();
attr.broadcast = !Config::IsNetworkEnabled();
attr.loopback = true;
attr.sndbuf = Config::GetUdpMulticastSndBufSizeBytes();

// create udp sample sender
// create udp registration sender
m_reg_sample_snd = std::make_shared<CSampleSender>(attr);
}
else
Expand Down
7 changes: 5 additions & 2 deletions ecal/core/src/ecal_registration_receiver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,15 +135,18 @@ namespace eCAL

if (m_use_network_monitoring)
{
// start registration receive thread
// set network attributes
SReceiverAttr attr;
attr.address = UDP::GetRegistrationMulticastAddress();
attr.address = UDP::GetRegistrationAddress();
attr.port = UDP::GetRegistrationPort();
attr.broadcast = !Config::IsNetworkEnabled();
attr.loopback = true;
attr.rcvbuf = Config::GetUdpMulticastRcvBufSizeBytes();

// create udp registration receiver
m_reg_rcv.Create(attr);

// start registration receiver thread
m_reg_rcv_thread.Start(0, std::bind(&CUdpRegistrationReceiver::Receive, &m_reg_rcv_process, &m_reg_rcv, CMN_REGISTRATION_RECEIVE_THREAD_CYCLE_TIME_MS));
}

Expand Down
87 changes: 63 additions & 24 deletions ecal/core/src/io/udp_configurations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,70 +28,109 @@ namespace eCAL
{
namespace UDP
{
std::string LocalBroadcastAddress()
/**
* @brief GetLocalBroadcastAddress retrieves the broadcast address within the loopback range.
*
* This function returns the specific broadcast address 127.255.255.255, which is within
* the loopback range (127.0.0.0 to 127.255.255.255). It is commonly used for local
* communication within the same machine. Keep in mind that broadcasting to this address
* will only reach processes running on the same host.
*
* @return The loopback broadcast address "127.255.255.255" as a string.
*/
std::string GetLocalBroadcastAddress()
{
// the specific address 127.255.255.255 is the broadcast address within the loopback range (127.0.0.0 to 127.255.255.255)
return "127.255.255.255";
}

std::string GetRegistrationMulticastAddress()
std::string GetRegistrationAddress()
{
// check if the network is disabled
const bool local_only = !Config::IsNetworkEnabled();
if (local_only)
{
return LocalBroadcastAddress();
}
else
{
// both in v1 and v2, the mulicast group is returned as the adress for the registration layer
return Config::GetUdpMulticastGroup();
return GetLocalBroadcastAddress();
}

// both in v1 and v2, the multicast group is returned as the adress for the registration layer
return Config::GetUdpMulticastGroup();
}

int GetRegistrationPort()
{
return Config::GetUdpMulticastPort() + NET_UDP_MULTICAST_PORT_REG_OFF;
// retrieve the configured UDP multicast port from the configuration
const int configured_port = Config::GetUdpMulticastPort();

// add the specific offset, NET_UDP_MULTICAST_PORT_REG_OFF, to obtain the registration port
return configured_port + NET_UDP_MULTICAST_PORT_REG_OFF;
}

std::string GetLoggingMulticastAddress()
std::string GetLoggingAddress()
{
// both logging and monitoring use the same addresses but different ports
return GetRegistrationMulticastAddress();
// registration, logging and payload use the same addresses but different ports
return GetRegistrationAddress();
}

int GetLoggingPort()
{
return Config::GetUdpMulticastPort() + NET_UDP_MULTICAST_PORT_LOG_OFF;
// retrieve the configured UDP multicast port from the configuration
const int configured_port = Config::GetUdpMulticastPort();

// add the specific offset, NET_UDP_MULTICAST_PORT_LOG_OFF, to obtain the logging port
return configured_port + NET_UDP_MULTICAST_PORT_LOG_OFF;
}

std::string GetPayloadAddress()
{
// registration, logging and payload use the same addresses but different ports
return GetRegistrationAddress();
}

std::string GetPayloadMulticastAddress(const std::string& topic_name)
std::string GetTopicPayloadAddress(const std::string& topic_name)
{
// v1
// check if the network is disabled
const bool local_only = !Config::IsNetworkEnabled();
if (local_only)
{
// if network is disabled, return the local broadcast address
return GetLocalBroadcastAddress();
}

// determine the UDP multicast configuration version
if (Config::GetUdpMulticastConfigVersion() == Config::UdpConfigVersion::V1)
{
// retrieve the corresponding multicast address based on the topic name using v1 implementation
return UDP::V1::topic2mcast(topic_name, Config::GetUdpMulticastGroup(), Config::GetUdpMulticastMask());
}

// v2
return UDP::V2::topic2mcast(topic_name, Config::GetUdpMulticastGroup(), Config::GetUdpMulticastMask());
else
{
// retrieve the corresponding multicast address based on the topic name using v2 implementation
return UDP::V2::topic2mcast(topic_name, Config::GetUdpMulticastGroup(), Config::GetUdpMulticastMask());
}
}

int GetPayloadPort()
{
return Config::GetUdpMulticastPort() + NET_UDP_MULTICAST_PORT_SAMPLE_OFF;
// retrieve the configured UDP multicast port from the configuration
const int configured_port = Config::GetUdpMulticastPort();

// add the specific offset, NET_UDP_MULTICAST_PORT_SAMPLE_OFF, to obtain the payload port
return configured_port + NET_UDP_MULTICAST_PORT_SAMPLE_OFF;
}

int GetMulticastTtl()
{
// check if the network is disabled
const bool local_only = !Config::IsNetworkEnabled();
if (local_only)
{
return 1;
}
else
{
return Config::GetUdpMulticastTtl();
// if network is disabled, return a TTL of 0 to restrict multicast packets to the local machine
return 0;
}

// if network is enabled, return the configured UDP multicast TTL value
return Config::GetUdpMulticastTtl();
}
}
}
91 changes: 80 additions & 11 deletions ecal/core/src/io/udp_configurations.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,91 @@ namespace eCAL
{
namespace UDP
{
// return local broadcast address
std::string LocalBroadcastAddress();

// return the multicast adress/port used for sending/receiving the registration information
std::string GetRegistrationMulticastAddress();
/**
* @brief GetRegistrationAddress retrieves the UDP registration address based on network configuration.
*
* If the network mode is disabled, it returns the local broadcast address.
* Otherwise, it retrieves the UDP multicast group address from the global configuration.
*
* @return The UDP registration address based on the network configuration.
*/
std::string GetRegistrationAddress();

/**
* @brief GetRegistrationPort retrieves the registration port based on the configured UDP multicast port.
*
* This function adds an offset, NET_UDP_MULTICAST_PORT_SAMPLE_OFF, to the UDP multicast port
* obtained from the configuration. The resulting port is used for registration communication.
*
* @return The registration port calculated by adding an offset to the configured UDP multicast port.
*/
int GetRegistrationPort();

// return the multicast adress/port used for sending/receiving the logging information
std::string GetLoggingMulticastAddress();
/**
* @brief GetLoggingAddress retrieves the UDP logging address based on network configuration.
*
* If the network mode is disabled, it returns the local broadcast address.
* Otherwise, it retrieves the UDP multicast group address from the global configuration.
*
* @return The UDP logging address based on the network configuration.
*/
std::string GetLoggingAddress();

/**
* @brief GetLoggingPort retrieves the logging port based on the configured UDP multicast port.
*
* This function adds an offset, NET_UDP_MULTICAST_PORT_SAMPLE_OFF, to the UDP multicast port
* obtained from the configuration. The resulting port is used for logging communication.
*
* @return The logging port calculated by adding an offset to the configured UDP multicast port.
*/
int GetLoggingPort();

// return the multicast adress/port used for sending/receiving the topic payload
std::string GetPayloadMulticastAddress(const std::string& topic_name);
int GetPayloadPort();
/**
* @brief GetPayloadAddress retrieves the UDP payload address used as base address for udp receivers.
*
* If the network mode is disabled, it returns the local broadcast address.
* Otherwise, it retrieves the UDP multicast group address from the global configuration.
*
* @return The UDP payload address based on the network configuration.
*/
std::string GetPayloadAddress();

// return multicast udp package time to live setting
/**
* @brief GetTopicPayloadAddress retrieves the UDP payload address based on network configuration and the topic name.
*
* If the network mode is disabled, it returns the local broadcast address.
*
* If the topic name is empty, it returns base UDP multicast base group based on the global configuration.
*
* If a topic name is provided, it returns the payload address based on the topic name and
- * UDP multicast configuration.
*
* @param topic_name The name of the topic for which the payload address is requested.
*
* @return The payload address based on the network configuration and the topic name.
*/
std::string GetTopicPayloadAddress(const std::string& topic_name);

/**
* @brief GetPayloadPort retrieves the payload port based on the configured UDP multicast port.
*
* This function adds an offset, NET_UDP_MULTICAST_PORT_SAMPLE_OFF, to the UDP multicast port
* obtained from the configuration. The resulting port is used for payload communication.
*
* @return The payload port calculated by adding an offset to the configured UDP multicast port.
*/
int GetPayloadPort();

/**
* @brief GetMulticastTtl retrieves the Time-to-Live (TTL) value for UDP multicast communication.
*
* If the network is disabled, it returns a TTL value of 0, indicating that multicast
* packets should not be forwarded beyond the local machine.
* If the network is enabled, it retrieves the configured UDP multicast TTL value from global configuration.
*
* @return The TTL value for UDP multicast communication based on the network configuration.
*/
int GetMulticastTtl();
}
}
8 changes: 7 additions & 1 deletion ecal/core/src/mon/ecal_monitoring_threads.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,21 @@ namespace eCAL
CLoggingReceiveThread::CLoggingReceiveThread(LogMessageCallbackT log_cb_) :
m_network_mode(false), m_log_cb(log_cb_)
{
// set network attributes
SReceiverAttr attr;
attr.address = UDP::GetLoggingMulticastAddress();
attr.address = UDP::GetLoggingAddress();
attr.port = UDP::GetLoggingPort();
attr.broadcast = !Config::IsNetworkEnabled();
attr.loopback = true;
attr.rcvbuf = Config::GetUdpMulticastRcvBufSizeBytes();

// create udp logging receiver
m_log_rcv.Create(attr);

// start logging receiver thread
m_log_rcv_thread.Start(0, std::bind(&CLoggingReceiveThread::ThreadFun, this));

// allocate receive buffer
m_msg_buffer.resize(MSG_BUFFER_SIZE);
}

Expand Down
24 changes: 19 additions & 5 deletions ecal/core/src/readwrite/ecal_reader_udp_mc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ namespace eCAL
// LAYER
////////////////
CUDPReaderLayer::CUDPReaderLayer() :
started(false)
started(false),
local_mode(false)
{}

CUDPReaderLayer::~CUDPReaderLayer()
Expand All @@ -59,12 +60,18 @@ namespace eCAL

void CUDPReaderLayer::Initialize()
{
// set local mode
local_mode = !Config::IsNetworkEnabled();

// set network attributes
SReceiverAttr attr;
attr.address = Config::GetUdpMulticastGroup();
attr.address = UDP::GetPayloadAddress();
attr.port = UDP::GetPayloadPort();
attr.broadcast = false;
attr.broadcast = !Config::IsNetworkEnabled();
attr.loopback = true;
attr.rcvbuf = Config::GetUdpMulticastRcvBufSizeBytes();

// create udp receiver
rcv.Create(attr);
}

Expand All @@ -75,8 +82,12 @@ namespace eCAL
thread.Start(0, std::bind(&CDataReaderUDP::Receive, &reader, &rcv, CMN_PAYLOAD_RECEIVE_THREAD_CYCLE_TIME_MS));
started = true;
}

// we use udp broadcast in local mode
if (local_mode) return;

// add topic name based multicast address
const std::string mcast_address = UDP::GetPayloadMulticastAddress(topic_name_);
const std::string mcast_address = UDP::GetTopicPayloadAddress(topic_name_);
if (topic_name_mcast_map.find(mcast_address) == topic_name_mcast_map.end())
{
topic_name_mcast_map.emplace(std::pair<std::string, int>(mcast_address, 0));
Expand All @@ -87,7 +98,10 @@ namespace eCAL

void CUDPReaderLayer::RemSubscription(const std::string& /*host_name_*/, const std::string& topic_name_, const std::string& /*topic_id_*/)
{
const std::string mcast_address = UDP::GetPayloadMulticastAddress(topic_name_);
// we use udp broadcast in local mode
if (local_mode) return;

const std::string mcast_address = UDP::GetTopicPayloadAddress(topic_name_);
if (topic_name_mcast_map.find(mcast_address) == topic_name_mcast_map.end())
{
// this should never happen
Expand Down
1 change: 1 addition & 0 deletions ecal/core/src/readwrite/ecal_reader_udp_mc.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ namespace eCAL

private:
bool started;
bool local_mode;
CUDPReceiver rcv;
CThread thread;
CDataReaderUDP reader;
Expand Down
Loading
Loading