Overview
Features
Download
Documentation
Community
Add-Ons & Services

Poco::Net::DNS and ipv6

Please post support and help requests here.

Poco::Net::DNS and ipv6

Postby jbb » 04 Apr 2009, 13:36

First of all as this is my first post here I just want to say thank you to all involved for such a terific library. It's gone a long way to making c++ a viable platform for me to use again. I have one question so far -

The following program I wrote to try out the DNS classes does not return my hosts ipv6 addresses only its ipv4 address.
And I doing something wrong, or is this just not supported? The platform is windows vista and I have functioning ipv6 address on the machine.
I don't seem to get back any addresses from using DNS::resolve either when I give it the name of a host with ipv6 addresses.

Code: Select all
#include <iostream>

#include "Poco/format.h"
#include "Poco/Net/DNS.h"

using namespace std;
using namespace Poco;
using namespace Poco::Net;

int main()
{
   const HostEntry& he = DNS::thisHost();
   const HostEntry::AddressList& addr = he.addresses();
   
   for(HostEntry::AddressList::const_iterator i = addr.begin(); i != addr.end(); ++i)
   {
      cout << format("Address entry is %s\n", (*i).toString());
   }
   
}
jbb
 
Posts: 9
Joined: 04 Apr 2009, 13:28

Re: Poco::Net::DNS and ipv6

Postby alex » 04 Apr 2009, 18:03

For that to work, you'd have to have POCO_HAVE_IPv6 defined.

However, searching around, I could not find it defined (not even conditionally) anywhere, so I'll leave it to Guenter to clarify this issue. I did however found few spots where
Code: Select all
#if POCO_HAVE_IPv6
was coded instead of
Code: Select all
#if defined(POCO_HAVE_IPv6)
I have fixed that in SVN, rev. 1132 and 1133
alex
 
Posts: 1116
Joined: 11 Jul 2006, 16:27
Location: United_States

Re: Poco::Net::DNS and ipv6

Postby jbb » 05 Apr 2009, 11:26

Thank you for the reply.
I tried setting this and rebuilding the libraries and I get IPPROTO_IPV6 not defined errors on windows / vc++ express 2008.

EDIT: Ok I found the answer to this, you need to define _WIN32_WINNT=0x0501 to tell the header file you want to target a version of windows supporting this
jbb
 
Posts: 9
Joined: 04 Apr 2009, 13:28

Re: Poco::Net::DNS and ipv6

Postby jbb » 05 Apr 2009, 13:11

Follow up my own post -
With the definitions as above it builds but my test program still fails to work. It gives an exception because the length of the address for an ipv6 address doesn't seem to match the length of the ipv6 address structure. Investigating still...
jbb
 
Posts: 9
Joined: 04 Apr 2009, 13:28

Re: Poco::Net::DNS and ipv6

Postby jbb » 08 Apr 2009, 21:30

This code from IPAddress.cpp looks wrong to me.
The structures returned are not in_addr and in6_addr but sockaddr_in and sockaddr_in6 which means that not only do the length checks fail but its constructing the objects with the wrong part of the structure. I don't see how this can work even for ipv4

Am I missing something here?


Code: Select all
IPAddress::IPAddress(const void* addr, poco_socklen_t length)
{
   if (length == sizeof(struct in_addr))
      _pImpl = new IPv4AddressImpl(addr);
#if defined(POCO_HAVE_IPv6)
   else if (length == sizeof(struct in6_addr))
      _pImpl = new IPv6AddressImpl(addr);
#endif
   else throw Poco::InvalidArgumentException("Invalid address length passed to IPAddress()");
}
jbb
 
Posts: 9
Joined: 04 Apr 2009, 13:28

Re: Poco::Net::DNS and ipv6

Postby alex » 09 Apr 2009, 01:59

jbb wrote:This code from IPAddress.cpp looks wrong to me.
The structures returned are not in_addr and in6_addr but sockaddr_in and sockaddr_in6 which means that not only do the length checks fail but its constructing the objects with the wrong part of the structure. I don't see how this can work even for ipv4

Am I missing something here?


When you say "the structures returned" you mean "the structures passed in", right? I was not able to find anywhere within the framework sockaddr_in[6] passed as parameter.

For example, IPAddress is instantiated from SocketAddress::host():

Code: Select all
return IPAddress(&_addr.sin_addr, sizeof(_addr.sin_addr));


and

Code: Select all
return IPAddress(&_addr.sin6_addr, sizeof(_addr.sin6_addr));


for IPv6. In both cases in_addr is passed, not sockaddr_in.

Same thing in NetworkInterface:

Code: Select all
addr = IPAddress(&reinterpret_cast<const struct sockaddr_in*>(&ifr->ifr_addr)->sin_addr, sizeof(struct in_addr));
alex
 
Posts: 1116
Joined: 11 Jul 2006, 16:27
Location: United_States

Re: Poco::Net::DNS and ipv6

Postby jbb » 09 Apr 2009, 09:34

Sorry my apologies, I tried to simplify the problem to make it clear and ended up actually getting it entirely wrong.

The problem is this - this program works ok when compiled for IPv4 only but crashes when compiled for Ipv6 on vista

Code: Select all
#include <iostream>

#include "Poco/format.h"
#include "Poco/Net/DNS.h"

using namespace std;
using namespace Poco;
using namespace Poco::Net;

int main()
{
   const HostEntry& he = DNS::thisHost();
   const HostEntry::AddressList& addr = he.addresses();

   for (HostEntry::AddressList::const_iterator i = addr.begin(); i != addr.end(); ++i)
   {
      cout << format("Address entry %s\n", (*i).toString());
   }

}


It crashes in the very first line at this line in IPAddress::IPAddress as posted below
Code: Select all
   else throw Poco::InvalidArgumentException("Invalid address length passed to IPAddress()");

The reason is that the length argument seems to be the length of a sockaddr_ip6 not an in6_addr as coded but it works when not compiled to support IPv6.
Using the debugger, the code I posted in the previous post has the length and structure of an sockaddr_ip6 not an in6_addr so the code fails. Some earlier code is likely setting this incorrectly.

I know this is a bit vague but I'm not able to run the code from this computer. I will attempt to track it down later today but there is clearly a problem of some kind here when IP_HAVE_IPv6 is defined.
jbb
 
Posts: 9
Joined: 04 Apr 2009, 13:28

Re: Poco::Net::DNS and ipv6

Postby guenter » 09 Apr 2009, 10:27

Hi,

I guess I've found the root of the problem. It's in the HostEntry constructor that takes a struct addrinfo* argument. Here, we pass the ai->ai_addr member, which is a struct sockaddr and not a in_addr (or in6_addr).

Could you try out the following code and see if it fixes the issue?

Code: Select all
HostEntry::HostEntry(struct addrinfo* ainfo)
{
   poco_check_ptr (ainfo);
   
   for (struct addrinfo* ai = ainfo; ai; ai = ai->ai_next)
   {
      if (ai->ai_canonname)
      {
         _name.assign(ai->ai_canonname);
      }
      else if (ai->ai_addrlen && ai->ai_addr)
      {
         switch (ai->ai_addr->sa_family)
         {
         case AF_INET:
            _addresses.push_back(IPAddress(&reinterpret_cast<struct sockaddr_in*>(&ai->ai_addr)->sin_addr, sizeof(in_addr)));
            break;
         case AF_INET6:
            _addresses.push_back(IPAddress(&reinterpret_cast<struct sockaddr_in6*>(&ai->ai_addr)->sin6_addr, sizeof(in6_addr)));
            break;
         }
      }
   }
}
guenter
 
Posts: 1119
Joined: 11 Jul 2006, 16:27
Location: Austria

Re: Poco::Net::DNS and ipv6

Postby jbb » 09 Apr 2009, 10:46

Yes, I was suspicious about that code but hadn't had the chance to work out exactly what needed changing.
I will make this later on today and try it out.

I Suppose the ipv6 support has not been well tested as most people don't yet have ipv6 connectivity. Hopefully I can stress test some more of the library with ipv6 as I use more of it
jbb
 
Posts: 9
Joined: 04 Apr 2009, 13:28

Re: Poco::Net::DNS and ipv6

Postby guenter » 09 Apr 2009, 10:50

It hasn't been tested much at all (except for some limited testing under Mac OS X, which has IPv6 support enabled by default). However, we don't have an IPv6 network to do full tests, so any testing you could do would be much regarded.
guenter
 
Posts: 1119
Joined: 11 Jul 2006, 16:27
Location: Austria

Next

Return to Support

Who is online

Users browsing this forum: No registered users and 1 guest

cron