?

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

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