You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The $ACE_ROOT/include/makeinclude/platform_macros.GNU file
The simplest possible replication links to the appropriate platform-specific file in $ACE_ROOT/include/makeinclude/ for the above-listed platforms.
Contents of $ACE_ROOT/bin/MakeProjectCreator/config/default.features
n/a
AREA/CLASS/EXAMPLE AFFECTED:
The use of -ORBListenerInterfaces as documented fails. Also, the incoming pull request includes an extension new test of -ORBListenerInterfaces that, as written, failed before the changes to INET_Addr, Sock_Connect, SOCK_Dgram, etc. were applied, and now passes.
The problem effects:
Execution.
Synopsis
The configuration option -ORBListenerInterfaces does not work at all with an IPv6 address on the right side of the argument's equal sign. Additionally, undocumented behavior asserted by existing tests (use of the interface name instead of an IP address on the right side of the argument's equal sign) does not work for either IPv4 or IPv6.
Description
Documentation section 4. Connection Management and Protocol Selection addresses a configuration option -ORBPreferredInterfaces targetNetwork=localNetwork[,...]. That documentation includes such as examples as -ORBPreferredInterfaces *=*10,*=*20, referencing IPv4 addresses 192.168.1.10 and 192.168.1.20, and -ORBPreferredInterfaces *=127.0.0.1. This documentation does not mention IPv6, but the implication is that you could put full or wildcarded IPv6 addresses on either side of this equal sign in a similar manner as IPv4 addresses. We have not experimented with the full range of possibilities, but I can confirm that we are successfully using the setting -ORBPreferredInterfaces *=2001:470:c2bc:xxxx:xxxx:a062:c2fd:892e and similar (no errors, seems to work, etc., or is possibly being silently ignored).
Documentation section "4. TAO_UIPMC_Protocol_Factory" provides a similar configuration option -ORBListenerInterfaces targetNetwork=localNetwork[,...] | CopyPreferredInterfaces. It provides analog examples to -ORBPreferredInterfaces, indicating that the syntax is identical, and also details a special value CopyPreferredInterfaces to trigger copying the -ORBPreferredInterfaces value(s) to -ORBListenerInterfaces.
We first tried to use -ORBListenerInterfaces CopyPreferredInterfaces, but this resulted in BAD_PARAM errors. So instead we tried -ORBListenerInterfaces *=2001:470:c2bc:xxxx:xxxx:a062:c2fd:892e but this, too, resulted in BAD_PARAM errors, indicating I would need to dig further. Through extensive code-stepping in the debugger, I found two problem execution stacks:
The value of net_if is always an IPv6 address in my debugging. However, by documentation and experimentation, ::if_nametoindex does not accept IP addresses for the sole argument, and it always returns a 0 when an IP address is supplied. ::if_nametoindex requires an interface name, such as en0, eth1, utun2, etc., in order to return an interface index. So, it's not possible for this code to work. (Additional note: Existing tests in TAO/orbsvcs use options like -ORBPreferredInterfaces xxx=eth0 or -ORBPreferredInterfaces xxx=lo. CopyPreferredInterfaces results in eth0 or lo being copied, as expected, but at the above point in code execution, the value of net_if is "if=eth0" or "if=lo", not "eth0" or "lo", so that also results in if_nametoindex returning 0.)
Furthermore, inspecting the make_multicast_ifaddr6 implementation in more detail, this is also broken on Windows, where the value of net_if is also always an IPv6 address, because it's comparing net_if to the interface's adapter name or friendly name:
Comments throughout ACE/TAO code suggest that net_if should be an interface name at this point, not an IP address, but I could find no code anywhere that actually performed this conversion. net_if is taken from the right-hand side of the equal sign in -ORBListenerInterfaces and passed unchanged all the way down the stack.
My first instinct was to go somewhere up the stack and convert net_if from an IP address to an interface name, but it quickly became apparent this was not the correct choice. Doing so breaks make_multicast_ifaddr (the IPv4 branch of code). The difference lies in lmreq.ipv6mr_interface vs lmreq.imr_interface.s_addr. The kernel's IPv4 stack expects a source IP address (lmreq.imr_interface.s_addr), but the kernel's IPv6 stack expects a source interface unsigned index (lmreq.ipv6mr_interface)—inconsistent, but unchangeable. So make_multicast_ifaddr is implemented (*mostly) correctly, and net_if needs to be an IP address in order for it to be implemented correctly. Thus, make_multicast_ifaddr6 is what needed changes—specifically, to convert net_if from an IPv6 address into an interface name, or something similar. (*Additional note: make_multicast_ifaddr has the same undocumented behavior of accepting an interface name [and converting it to an IP address instead of an interface index], but it, too, suffers from the "if=eth0" / "if=lo" bug.)
The approach I took might not be the approach you want to take to fix this, but it's the patch we applied to our ACE/TAO copy that got this working. Notably:
There could be a simpler fix—I took the route of assuming that net_if could be either an IPv6 address or an interface name, and checked for both, because that's the existing behavior and also existing tests use this behavior, but maybe that wasn't necessary and this behavior can be removed and the tests changed.
There could be other places that net_if is incorrectly assumed to always be an IPv6 interface name, that I just didn't find because our use cases aren't hitting those code paths.
There could be similar problems with -ORBPreferredInterfaces that either cause it to silently be ignored or that we aren't encountering because our uses cases aren't hitting those code paths.
There could be other, system IPv6 deficiencies that we just haven't found yet (TAO appears to largely be working with IPv6 for us).
Repeat by
The incoming pull request has a new test $TAO_ROOT/orbsvcs/tests/Miop/McastListenerInterfaces. This test contains the code and configuration necessary to replicate the problem. It was implemented first, and failed. Then our patch was applied, and the test passed. NOTE In order for this test to compile and run, $TAO_ROOT/TAO_ACE.mwc has to be edited to comment out or remove the line orbsvcs/tests in the exclude block. It seems that all orbsvcs tests are currently disabled in master. I did not include this change in my pull request, because it seems those tests were disabled for a reason, which I won't second-guess. I know, for example, that most of the tests in $TAO_ROOT/orbsvcs/tests/Miop/ fail on a clean master.
Sample fix/ workaround
There is no workaround. -ORBListenerInterfaces does not work without changes. The incoming pull request is a fix that works, but you may prefer to fix it another way. Furthermore, on some macOS machines (I'm unable to find an explanation for why some and not others, but I can confirm that the macOS version is not a factor), IPv6 multicast traffic does not work at all without the -ORBListenerInterfaces config option, because macOS cannot determine which interface to use automatically. This could be an obscure macOS bug related to specific hardware versions.
The text was updated successfully, but these errors were encountered:
Note: Submission of this bug will be shortly followed by submission of a pull request to fix this bug and add a new test for it.
Version
ACE 7.0.9
TAO 3.0.9
Host machine and operating system
Target machine and operating system (if different from host)
n/a
Compiler name and version (including patch level)
See above; patch versions do not affect the outcome, because it's the same across every platform and compiler.
The $ACE_ROOT/ace/config.h file
Simplest possible one to replicate this problem:
Our full file:
The $ACE_ROOT/include/makeinclude/platform_macros.GNU file
The simplest possible replication links to the appropriate platform-specific file in
$ACE_ROOT/include/makeinclude/
for the above-listed platforms.Contents of $ACE_ROOT/bin/MakeProjectCreator/config/default.features
n/a
AREA/CLASS/EXAMPLE AFFECTED:
The use of
-ORBListenerInterfaces
as documented fails. Also, the incoming pull request includes an extension new test of-ORBListenerInterfaces
that, as written, failed before the changes to INET_Addr, Sock_Connect, SOCK_Dgram, etc. were applied, and now passes.The problem effects:
Execution.
Synopsis
The configuration option
-ORBListenerInterfaces
does not work at all with an IPv6 address on the right side of the argument's equal sign. Additionally, undocumented behavior asserted by existing tests (use of the interface name instead of an IP address on the right side of the argument's equal sign) does not work for either IPv4 or IPv6.Description
Documentation section 4. Connection Management and Protocol Selection addresses a configuration option
-ORBPreferredInterfaces targetNetwork=localNetwork[,...]
. That documentation includes such as examples as-ORBPreferredInterfaces *=*10,*=*20
, referencing IPv4 addresses192.168.1.10
and192.168.1.20
, and-ORBPreferredInterfaces *=127.0.0.1
. This documentation does not mention IPv6, but the implication is that you could put full or wildcarded IPv6 addresses on either side of this equal sign in a similar manner as IPv4 addresses. We have not experimented with the full range of possibilities, but I can confirm that we are successfully using the setting-ORBPreferredInterfaces *=2001:470:c2bc:xxxx:xxxx:a062:c2fd:892e
and similar (no errors, seems to work, etc., or is possibly being silently ignored).Documentation section "4. TAO_UIPMC_Protocol_Factory" provides a similar configuration option
-ORBListenerInterfaces targetNetwork=localNetwork[,...] | CopyPreferredInterfaces
. It provides analog examples to-ORBPreferredInterfaces
, indicating that the syntax is identical, and also details a special valueCopyPreferredInterfaces
to trigger copying the-ORBPreferredInterfaces
value(s) to-ORBListenerInterfaces
.We first tried to use
-ORBListenerInterfaces CopyPreferredInterfaces
, but this resulted inBAD_PARAM
errors. So instead we tried-ORBListenerInterfaces *=2001:470:c2bc:xxxx:xxxx:a062:c2fd:892e
but this, too, resulted inBAD_PARAM
errors, indicating I would need to dig further. Through extensive code-stepping in the debugger, I found two problem execution stacks:ACE_SOCK_Dgram_Mcast::join -> ACE_SOCK_Dgram_Mcast::subscribe_i -> ACE_SOCK_Dgram_Mcast::open -> ACE_SOCK_Dgram_Mcast::open_i -> ACE_SOCK_Dgram::set_nic -> ACE_SOCK_Dgram::make_multicast_ifaddr6 -> ACE_OS::if_nametoindex -> ::if_nametoindex
ACE_SOCK_Dgram_Mcast::join -> ACE_SOCK_Dgram_Mcast::subscribe_i -> ACE_SOCK_Dgram::make_multicast_ifaddr6 -> ACE_OS::if_nametoindex -> ::if_nametoindex
No matter the circumstances (or use of
CopyPreferredInterfaces
vs thex=x
syntax), at the point that this code executes:The value of
net_if
is always an IPv6 address in my debugging. However, by documentation and experimentation,::if_nametoindex
does not accept IP addresses for the sole argument, and it always returns a 0 when an IP address is supplied.::if_nametoindex
requires an interface name, such asen0
,eth1
,utun2
, etc., in order to return an interface index. So, it's not possible for this code to work. (Additional note: Existing tests inTAO/orbsvcs
use options like-ORBPreferredInterfaces xxx=eth0
or-ORBPreferredInterfaces xxx=lo
.CopyPreferredInterfaces
results ineth0
orlo
being copied, as expected, but at the above point in code execution, the value ofnet_if
is"if=eth0"
or"if=lo"
, not"eth0"
or"lo"
, so that also results inif_nametoindex
returning 0.)Furthermore, inspecting the
make_multicast_ifaddr6
implementation in more detail, this is also broken on Windows, where the value ofnet_if
is also always an IPv6 address, because it's comparingnet_if
to the interface's adapter name or friendly name:Comments throughout ACE/TAO code suggest that
net_if
should be an interface name at this point, not an IP address, but I could find no code anywhere that actually performed this conversion.net_if
is taken from the right-hand side of the equal sign in-ORBListenerInterfaces
and passed unchanged all the way down the stack.My first instinct was to go somewhere up the stack and convert
net_if
from an IP address to an interface name, but it quickly became apparent this was not the correct choice. Doing so breaksmake_multicast_ifaddr
(the IPv4 branch of code). The difference lies inlmreq.ipv6mr_interface
vslmreq.imr_interface.s_addr
. The kernel's IPv4 stack expects a source IP address (lmreq.imr_interface.s_addr
), but the kernel's IPv6 stack expects a source interface unsigned index (lmreq.ipv6mr_interface
)—inconsistent, but unchangeable. Somake_multicast_ifaddr
is implemented (*mostly) correctly, andnet_if
needs to be an IP address in order for it to be implemented correctly. Thus,make_multicast_ifaddr6
is what needed changes—specifically, to convertnet_if
from an IPv6 address into an interface name, or something similar. (*Additional note:make_multicast_ifaddr
has the same undocumented behavior of accepting an interface name [and converting it to an IP address instead of an interface index], but it, too, suffers from the"if=eth0"
/"if=lo"
bug.)The approach I took might not be the approach you want to take to fix this, but it's the patch we applied to our ACE/TAO copy that got this working. Notably:
net_if
could be either an IPv6 address or an interface name, and checked for both, because that's the existing behavior and also existing tests use this behavior, but maybe that wasn't necessary and this behavior can be removed and the tests changed.net_if
is incorrectly assumed to always be an IPv6 interface name, that I just didn't find because our use cases aren't hitting those code paths.-ORBPreferredInterfaces
that either cause it to silently be ignored or that we aren't encountering because our uses cases aren't hitting those code paths.Repeat by
The incoming pull request has a new test
$TAO_ROOT/orbsvcs/tests/Miop/McastListenerInterfaces
. This test contains the code and configuration necessary to replicate the problem. It was implemented first, and failed. Then our patch was applied, and the test passed. NOTE In order for this test to compile and run,$TAO_ROOT/TAO_ACE.mwc
has to be edited to comment out or remove the lineorbsvcs/tests
in theexclude
block. It seems that allorbsvcs
tests are currently disabled inmaster
. I did not include this change in my pull request, because it seems those tests were disabled for a reason, which I won't second-guess. I know, for example, that most of the tests in$TAO_ROOT/orbsvcs/tests/Miop/
fail on a cleanmaster
.Sample fix/ workaround
There is no workaround.
-ORBListenerInterfaces
does not work without changes. The incoming pull request is a fix that works, but you may prefer to fix it another way. Furthermore, on some macOS machines (I'm unable to find an explanation for why some and not others, but I can confirm that the macOS version is not a factor), IPv6 multicast traffic does not work at all without the-ORBListenerInterfaces
config option, because macOS cannot determine which interface to use automatically. This could be an obscure macOS bug related to specific hardware versions.The text was updated successfully, but these errors were encountered: