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.
July 20, 2010 at 3:24 pm |
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
July 21, 2010 at 8:00 am |
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…
January 19, 2012 at 8:39 am |
Can u please inform me how to use IPV6 In my ACE Server?
January 19, 2012 at 10:59 am |
I recommend you look at ACE_wrappers/tests/SOCK_Send_Recv_Test_IPV6.cpp for hints on how to use IPv6 in ACE.
January 20, 2012 at 4:50 am
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..
January 20, 2012 at 7:24 am |
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.
January 27, 2012 at 6:36 am |
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.
April 15, 2015 at 3:15 am |
Hi,
Thanks in advance!
I have added ACE_HAS_IPV6 to preprocessor list in vs2010.
But when I call
ACE_INET_Addr addr(port, host, AF_INET6);
addr.get_ip_address(); //Here I get return value = 0 and ACE trace as “ACE_INET_Addr::get_ip_address: address is a IPv6 address not IPv4”
Debugging shows that inside ACE_INET_Addr::get_ip_address(), IN6_IS_ADDR_V4MAPPED and IN6_IS_ADDR_V4COMPAT both return false, any other preprocessor directives along with ACE_HAS_IPV6 do i need to set?
Any help please?
April 15, 2015 at 6:01 pm |
Looks like the address is regular IPv6, not v4 compatible. The get_ip_address() method returns a 32-bit IPv4 address, so it can’t work with IPv6. If you really want the binary IP address, try get_addr()
April 16, 2015 at 12:10 am |
Thanks Steve,
so for ipv4
addr.get_ip_address();
and for ipv6
addr.get_addr(); //But get_addr() returns void*
Is that correct?
April 16, 2015 at 2:13 pm |
Yes. get_addr() also works for IPv4, but get_ip_address() is easier.
April 16, 2015 at 8:18 am |
Hi steve,
I could build ACE with ipv6 (ACE_HAS_IPV6) for 32 bit, but when I do it for 64 bit, my application code while building gets following errors:
ace.6.1.0_versioned_vc10\ace/INET_Addr.inl(184): error C3861: ‘IN6_IS_ADDR_UNSPECIFIED’: identifier not found
ace.6.1.0_versioned_vc10\ace/INET_Addr.inl(196): error C3861: ‘IN6_IS_ADDR_LOOPBACK’: identifier not found
ace.6.1.0_versioned_vc10\ace/INET_Addr.inl(222): error C3861: ‘IN6_IS_ADDR_LINKLOCAL’: identifier not found
ace.6.1.0_versioned_vc10\ace/INET_Addr.inl(232): error C3861: ‘IN6_IS_ADDR_V4MAPPED’: identifier not found
ace.6.1.0_versioned_vc10\ace/INET_Addr.inl(242): error C3861: ‘IN6_IS_ADDR_V4COMPAT’: identifier not found
How to fix this issue?
Regards,
Amey
April 16, 2015 at 2:13 pm |
For some reason the proper ipv6 headers aren’t being pulled in. You don’t see it during ACE build because inlines are on so the methods triggering the error aren’t compiled.
April 17, 2015 at 12:27 am |
Thats Ok, but what should I do, to get rid of above compilation errors?
April 17, 2015 at 9:51 am |
I don’t have a good answer, since I don’t see that error in builds here. In general, I would suggest finding out which header files define those symbols, then look for why they aren’t being included.