Trouble with ACE and IPv6? Make Sure Your Config is Consistent

I just spent about 5 hours over the week debugging a stack corruption problem. The MSVC debugger was politely telling me the stack was corrupted in the area of an ACE_INET_Addr object instantiated on the stack. But all I did was create it then return from the method. So the problem had to be localized pretty well. Also, I was seeing the problem but none of the students in the class I was working this example for saw the problem. So it was somehow specific to my ACE build.

I stepped through the ACE_INET_Addr constructor and watched it clear the contents of the internal sockaddr to zeroes. Fine. I noted it was clearing 28 bytes and setting address family 23. “IPv6. Ok, ” I thought. But I knew the stack was being scribbled on outside the bounds of that ACE_INET_Addr object. I checked to see if ACE somehow had a bad definition of sockaddr_in6. After rummaging around ACE and Windows SDK headers I was pretty sure that wasn’t it. But there was definitely some confusion on the size of what needed to be cleared.

If you haven’t looked at the ACE_INET_Addr internals (and, really, why would you?), when ACE is built with IPv6 support (the ACE_HAS_IPV6 setting) the internal sockaddr is a union of socketaddr_in and sockaddr_in6 so both IPv4 and IPv6 can be supported. The debugger inside the ACE_INET_Addr constructor was showing me both v4 and v6 members of the union. But as I stepped out of the ACE_INET_Addr constructor back to the example application, the debugger changed to only showing the IPv4 part. Hmmm… why is that? The object back in the example is suddenly looking smaller (since the sockaddr_in6 structure is larger than the sockaddr_in structure, the union gets smaller when you leave out the sockaddr_in6). Ok, so now I know why the stack is getting smashed… I’m passing a IPv4-only ACE_INET_Addr object to a method that thinks it’s getting a IPv4-or-IPv6 object which is larger. But why?

I checked my $ACE_ROOT/ace/config.h since that’s where ACE config settings usually are. No ACE_HAS_IPV6 setting there. Did the ACE-supplied Windows configs add it in somewhere sneakily? Nope. I checked the ACE.vcproj file ACE was built with. Ah-ha… in the compile preprocessor settings there it is – ACE_HAS_IPV6.

AAAAARRRRRGGGGGGG!!!!! Now I remember where it came from. IPv6 support is turned on/off in the MPC-generated Visual Studio projects using an MPC feature setting, ipv6=1 (this is because some parts of ACE and tests aren’t included without the ipv6 feature). When I generated the ACE projects that setting was used, but when I generated the example program’s projects it wasn’t. So the uses of ACE_INET_Addr in the example had only the IPv4 support, but were passed to an ACE build that was expecting both IPv4 and IPv6 support – a larger object.

Solution? Regenerate the example’s projects with the same MPC feature file ACE’s projects were generated with. That made all the settings consistent between ACE and my example programs. No more stack scribbling.

About these ads

7 Responses to “Trouble with ACE and IPv6? Make Sure Your Config is Consistent”

  1. Ken Sedgwick Says:

    Isn’t it a better solution to guarantee that all preprocessor settings which affect data object size be defined in $ACE_ROOT/ace/config.h instead of only being generated at compile time?

    This is the approach I’ve taken when packaging ACE+TAO rpm for linux; I attempt to set all such preprocessor settings explicitly in config.h to avoid this problem …

    Ken

    • stevehuston Says:

      I completely agree, Ken! The ipv6 enabling switch in MPC got treated differently and I was on the losing side of the debate when it happened. In the MPC generation there’s no way to set a config.h macro. As long as the user projects also use MPC everything is ok, but if not, there could be trouble, as I re-learned…

  2. Steve Says:

    Can u please inform me how to use IPV6 In my ACE Server?

    • stevehuston Says:

      I recommend you look at ACE_wrappers/tests/SOCK_Send_Recv_Test_IPV6.cpp for hints on how to use IPv6 in ACE.

      • Steve Says:

        when i am trying to connect IPV6 server from the client its giving me error ACE_INETAddr:: ::1 : No such process

        can u please tell me why this error is coming..

  3. stevehuston Says:

    Steve… the blog is not a very effective way to answer detailed support questions. I recommend you fill out the PROBLEM-REPORT-FORM located in ACE_wrappers, include the code that’s causing the error, and either post it to ace-users or open a support contract with Riverace for resolution.

    • Steve Says:

      thanks stevehuston.
      but can u just please tell me how to enable ipv6? i have added #define ACE_HAS_IPV6 but the values returnd by ACE::ipv6_enabled() is still 0.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Follow

Get every new post delivered to your Inbox.

Join 222 other followers

%d bloggers like this: