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

IPv6 Interface Whitelisting Does Not Work [11278] #1923

Closed
Craig-Trimble opened this issue Apr 20, 2021 · 5 comments · Fixed by #1969
Closed

IPv6 Interface Whitelisting Does Not Work [11278] #1923

Craig-Trimble opened this issue Apr 20, 2021 · 5 comments · Fixed by #1969

Comments

@Craig-Trimble
Copy link

Craig-Trimble commented Apr 20, 2021

When creating a UDPv6TransportDescriptor with an interface whitelist, Fast-DDS discovery fails.
When creating the equivalent UDPv4TransportDescriptor, Fast-DDS discovery succeeds.

Looking at #346, a fix was implemented to make this work for IPv4, but the equivalent fix was not made for IPv6.

Expected Behavior

Using the whitelisted interface, the Fast-DDS discovery process should find all instances on the network.

Current Behavior

It appears as the the discovery multi-cast group isn't joined on the white-listed interface

Steps to Reproduce

  1. Assign a UDPv6TransportDescriptor with a interfaceWhiteList to the DomainParticipantQos
  2. Add a valid metatrafficMulticastLocator, and default_multicast_locator to the Qos
  3. Create a participant with the QoS, and publisher/subscriber from that
  4. Run multiple instances on the network, and the Fast-DDS apps will not discover each other
  5. Remove the interfaceWhiteList, and discovery will work.

System information

  • Fast-RTPS version: v2.3.0
  • OS: Ubuntu 18.04
  • Network interfaces: 2001::1 (global addressable ipv6 address)

Additional context

#346

Additional resources

I hacked in the following code, based on the pull-request made for IPv4, and the interface whitelisting worked for my situation.

diff --git a/src/cpp/rtps/transport/UDPv6Transport.cpp b/src/cpp/rtps/transport/UDPv6Transport.cpp
index 5118505dc..c09c70c5d 100644
--- a/src/cpp/rtps/transport/UDPv6Transport.cpp
+++ b/src/cpp/rtps/transport/UDPv6Transport.cpp
@@ -341,6 +341,45 @@ bool UDPv6Transport::OpenInputChannel(

     if (IPLocator::isMulticast(locator) && IsInputChannelOpen(locator))
     {
+#ifndef _WIN32
+        if (!is_interface_whitelist_empty())
+        {
+            std::string locatorAddressStr = IPLocator::toIPv6string(locator);
+            // Either wildcard address or the multicast address needs to be bound on non-windows systems
+            bool found = false;
+
+            // First check if the multicast address is already bound
+            auto& channelResources = mInputSockets.at(IPLocator::getPhysicalPort(locator));
+            for (UDPChannelResource* channelResource : channelResources)
+            {
+                if (channelResource->interface() == locatorAddressStr)
+                {
+                    found = true;
+                    break;
+                }
+            }
+
+            // Create a new resource if no one is found
+            if (!found)
+            {
+                try
+                {
+                    // Bind to multicast address
+                    UDPChannelResource* p_channel_resource;
+                    p_channel_resource = CreateInputChannelResource(locatorAddressStr, locator, true, maxMsgSize,
+                                    receiver);
+                    mInputSockets[IPLocator::getPhysicalPort(locator)].push_back(p_channel_resource);
+                }
+                catch (asio::system_error const& e)
+                {
+                    (void)e;
+                    logWarning(RTPS_MSG_OUT, "UDPTransport Error binding " << locatorAddressStr << " at port: (" << IPLocator::getPhysicalPort(
+                                locator) << ")"
+                                                                           << " with msg: " << e.what());
+                }
+            }
+        }
+#endif // ifndef _WIN32
         // The multicast group will be joined silently, because we do not
         // want to return another resource.
         auto pChannelResources = mInputSockets.at(IPLocator::getPhysicalPort(locator));
@EduPonz EduPonz changed the title IPv6 Interface Whitelisting Does Not Work IPv6 Interface Whitelisting Does Not Work [11278] Apr 20, 2021
@EduPonz
Copy link

EduPonz commented Apr 20, 2021

Hi @Craig-Trimble ,

Thanks for your report! I've added your ticket to be tackled in the next week or so. We'll keep you posted

@Craig-Trimble
Copy link
Author

Related to this, I've found that (with the above fix) the multicast group is joined on the default interface, rather than the interface of the interfaceWhiteList address.

Even specifying the scope_id in the IPv6 address "eg, %eth0" doesn't get the correct scope used - it's always zero.
I have four systems each with an eth0 and wlan0. My Fast-DDS app picks different interfaces on the different systems to join the multicast group on. This leads to discovery not happening for the systems that have there default scope as wlan0.

Disabling the wlan0 interface on all the systems makes everything work as expected.

@JLBuenoLopez
Copy link
Contributor

Hi @Craig-Trimble,

We have this draft PR (#1969) that we believe can solve your issue. We have found that we were not testing this feature thoroughly so we are going to keep it in draft while we add some more tests to ensure that the feature works correctly. Your feedback telling if this PR solves your issue is most welcomed. Thanks for your waiting!

@Craig-Trimble
Copy link
Author

Craig-Trimble commented May 18, 2021 via email

@Craig-Trimble
Copy link
Author

I just ran my use case, and confirmed that everything was working with the change. Nice work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants