?

Log in

No account? Create an account

Solaris, IPV6, getnameinfo() completely busted?

« previous entry | next entry »
Jan. 4th, 2008 | 11:25 am

Dear LazyWeb,

No matter how I modify this following code it does not work with Solaris. Solaris always returns "non-recoverable name resolution failure":

     int error;
     char port_buf[NI_MAXSERV];
     size_socket addrLen = sizeof(vio->remote);
     if (getpeername(vio->sd, (struct sockaddr *) (&vio->remote),
                     &addrLen) != 0)
     {
       DBUG_PRINT("exit", ("getpeername gave error: %d", socket_errno));
       DBUG_RETURN(1);
     }

     if ((error= getnameinfo((struct sockaddr *)(&vio->remote),
                             sizeof(struct sockaddr_storage),
                             buf, buflen,
                             port_buf, NI_MAXSERV, NI_NUMERICHOST|NI_NUMERICSERV)))
     {
       WATCHPOINT_STRING(gai_strerror(error));
       DBUG_PRINT("exit", ("getnameinfo gave error: %s",
                           gai_strerror(error)));
       DBUG_RETURN(1);
     }




Linux, FreeBSD, OSX, AIX, Windows.... all are fine. Except Solaris. For DNS resolution nsswitch.conf lists files, then DNS.

I am completely capable of FUBAR code myself. So some part of me really does believe this is my mistake. When I google for "non-recoverable name resolution failure" and Solaris I get plenty of hits though, so I am skeptical.

Very few open source projects have good IPv6 support at this time, so it is not like I can just poke around and other groups code and see how they are doing it (though I am tempted to fire off some patches...).

(...and yes this is MySQL, and if I have to all platforms but Solaris get IPv6 support, I have a very low tolerance for work arounds on broken operating systems).

Link | Leave a comment |

Comments {18}

Brian "Krow" Aker

(no subject)

from: krow
date: Jan. 5th, 2008 10:06 am (UTC)
Link

I just pulled the source to Python 3, I believe their second Alpha.

Their IPv6 code is pretty poor. They are using older interfaces and because of this setting up locks they do not need. All in all, pretty lousy.

They are though using the right structures, so fixing the code is not a huge deal.


Reply | Parent | Thread

Lover of Ideas

(no subject)

from: omnifarious
date: Jan. 5th, 2008 10:28 am (UTC)
Link

Well, I guess I stand corrected then. I was speaking of their support from the standpoint of actually using the APIs. I know that when I've tested things I've gotten all the information I ever needed about how to reach a particular host. I guess though, that if they're using older APIs this doesn't help you understand what's going on with your Solaris code.

The IPv6 APIs for name resolution and such have been in flux for quite awhile. I haven't ever examined them really closely as most of my programming since about 2003 has been in Python. I should research what the most recent thing to do is supposed to be now.

Reply | Parent | Thread

Brian "Krow" Aker

(no subject)

from: krow
date: Jan. 5th, 2008 05:14 pm (UTC)
Link

It would be easy to patch up Python from looking at the code. It would move quite a few of their IFDEF as well.


Reply | Parent | Thread

Lover of Ideas

Well, now I have to actually look at your code

from: omnifarious
date: Jan. 5th, 2008 10:39 am (UTC)
Link

So, I'm really curious as to whether or not Solaris is the problem or not. I have no Solaris box I can test on, so here are the potential problems I see in your code:

  • Why use sizeof(struct sockaddr_storage) instead of addrLen in the call to getnameinfo?
  • Where do buf and buflen come from? buf is supposed to be filled by getnameinfo so buflen instead of sizeof(buf) seems like it might be confusing there.
  • Minor, unimportant nitpick... you should use sizeof(port_buf) instead of NI_MAXSERV. If you ever change how big port_buf for some reason, he code you have might cause problems.

I don't know if any of these things are actually problems or not. They're just what jump out at me when I read your code.



Edited at 2008-01-05 10:40 am (UTC)

Reply | Parent | Thread

Brian "Krow" Aker

Re: Well, now I have to actually look at your code

from: krow
date: Jan. 5th, 2008 05:13 pm (UTC)
Link

1) addrLen is filled (notice is passes a pointer).
2) Those variables are passed.
3) NI_MAXSERV is defined by RFC (in netdb.h). That is the maximum length of a service record.

Reply | Parent | Thread

Lover of Ideas

Re: Well, now I have to actually look at your code

from: omnifarious
date: Jan. 5th, 2008 05:29 pm (UTC)
Link

Right, in the call to getpeername, &addrLen is passed in so it can be filled in by getpeername. But then iwhen you call getnameinfo you don't pass in addrLen for the length of the address. Instead you pass in sizeof(struct sockaddr_storage). getnameinfo reads the address out of the sockaddr structure, so it like wants the real length of the address, not some length that is guaranteed to be larger.


This is, in fact, the only problem I can see with your code that might cause it not to work. Try passing in addrLen as the second argument for getnameinfo.

Reply | Parent | Thread

Brian "Krow" Aker

Re: Well, now I have to actually look at your code

from: krow
date: Jan. 5th, 2008 06:09 pm (UTC)
Link

You are partially right... but it leads to where the bug is I suspect on the Solaris side.

I need to dig into libc and see if I can find out what is so different... but you are right in that passing the length of the address seems to matter to Solaris, but not to any other OS (well... passing address is ok to Linux, I will have to push to find out more).

Thank you!




Reply | Parent | Thread