SCTP Discussions

Text archives Help


[SCTP-Discussion] _res.options interaction with solaris 9.


Chronological Thread 
  • From: rcl AT ihug.co.nz
  • To: discussion AT sctp.de
  • Subject: [SCTP-Discussion] _res.options interaction with solaris 9.
  • Date: Mon May 22 23:42:03 2006
  • List-id: SCTP Discussions <discussion.sctp.de>
  • Priority: normal

Hi,

There is an unfortunate bug in Solaris 9 (at some
patchlevels anyway), where setting _res.options (as done in
socketapi/internetaddress.cc) causes getaddrinfo to return
incorrect results.

It would be nice to work around this - while the problem is
not in your code, it is triggered by socketapi, and is quite
nasty and obscure to track down.

A test program that illustrates the problem is below.

Rather than setting _res.options, you should be able to do
set:

hints.ai_family = AF_UNSPEC;
hints.ai_flags = AI_ADDRCONFIG

for your calls to getaddrinfo() - I think using
AI_ADDRCONFIG should achieve much the same as setting
RES_USE_INET6, but is a standard mechanism, and does not
change global state.

A patch is attached (it also fixes some trivial compile
problems with gcc-4). I do not have an IPv6 network, so it
is not properly tested.

Ralph

PS. here is the output from the test program on my solaris
9 box. After setting _res.options|=RES_USE_INET6,
getaddrinfo() starts returning 0.0.0.0:

Lookup: www.google.com 12345
AF = 2
66.102.7.147 12345
AF = 2
66.102.7.99 12345
AF = 2
66.102.7.104 12345
Setting _res.options |= RES_USE_INET6;
Lookup: www.google.com 12345
AF = 2
0.0.0.0 12345
AF = 2
0.0.0.0 12345
AF = 2
0.0.0.0 12345
#include <arpa/inet.h>
#include <netdb.h>
#include <resolv.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static void dolookup (const char * host, const char * port)
{
    struct addrinfo hints;
    struct addrinfo * ai;
    struct addrinfo * p;
    int r;

    memset (&hints, 0, sizeof (hints));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;

    fprintf (stderr, "Lookup: %s %s\n", host, port);

    r = getaddrinfo (host, port, &hints, &ai);
    if (r != 0) {
        fprintf (stderr, "getaddrinfo: %s\n", gai_strerror (r));
        return;
    }

    for (p = ai; p != NULL; p = p->ai_next) {
        printf ("AF = %i\n", p->ai_addr->sa_family);
        if (p->ai_addr->sa_family == AF_INET) {
            printf ("        %s %d\n",
                    inet_ntoa (
                        ((struct sockaddr_in *) p->ai_addr)->sin_addr),
                    ntohs (
                        ((struct sockaddr_in *) p->ai_addr)->sin_port));
        }
    }

    freeaddrinfo (ai);

    fflush (NULL);
}

int main (int argc, char ** argv)
{
    dolookup ("www.google.com", "12345");

    printf ("Setting _res.options |= RES_USE_INET6;\n");
    _res.options |= RES_USE_INET6;

    dolookup ("www.google.com", "12345");

    exit (EXIT_SUCCESS);
}
diff -ur orig/socketapi-1.7.0/socketapi/internetaddress.cc socketapi-1.7.0/socketapi/internetaddress.cc
--- orig/socketapi-1.7.0/socketapi/internetaddress.cc	2005-09-16 22:07:50.000000000 +1200
+++ socketapi-1.7.0/socketapi/internetaddress.cc	2006-05-23 09:27:50.000000000 +1200
@@ -578,9 +578,6 @@
    int result = socket(AF_INET6,SOCK_DGRAM,0);
    if(result != -1) {
       close(result);
-#if (SYSTEM != OS_Darwin)
-      _res.options |= RES_USE_INET6;
-#endif
       return(true);
    }
    else {
@@ -611,7 +608,8 @@
    addrinfo* res = NULL;
    memset((char*)&hints,0,sizeof(hints));
    hints.ai_socktype = SOCK_DGRAM;
-   hints.ai_family   = (UseIPv6 == true) ? AF_UNSPEC : AF_INET;
+   hints.ai_family   = AF_UNSPEC;
+   hints.ai_flags    = AI_ADDRCONFIG;
    const char* name = hostName.getData();
 
    // Avoid DNS lookups for IP addresses
diff -ur orig/socketapi-1.7.0/socketapi/sctpassociation.h socketapi-1.7.0/socketapi/sctpassociation.h
--- orig/socketapi-1.7.0/socketapi/sctpassociation.h	2005-09-16 22:07:51.000000000 +1200
+++ socketapi-1.7.0/socketapi/sctpassociation.h	2006-05-23 09:26:36.000000000 +1200
@@ -47,7 +47,9 @@
 
 #include <sctp.h>
 
-
+class SCTPSocket;
+class SCTPConnectionlessSocket;
+class SCTPSocketMaster;
 
 /**
   * This structure contains defaults for an association.
Only in socketapi-1.7.0/socketapi: sctpassociation.h~
diff -ur orig/socketapi-1.7.0/socketapi/sctpsocket.h socketapi-1.7.0/socketapi/sctpsocket.h
--- orig/socketapi-1.7.0/socketapi/sctpsocket.h	2005-09-16 22:07:51.000000000 +1200
+++ socketapi-1.7.0/socketapi/sctpsocket.h	2006-05-23 09:27:12.000000000 +1200
@@ -51,6 +51,10 @@
 #include <map>
 
 
+class SCTPSocketMaster;
+class SCTPAssociation;
+
+
 /**
   * This class manages a SCTP socket (SCTP instance).
   *
@@ -577,7 +581,7 @@
    private:
    void checkAutoConnect();
    void checkAutoClose();
-   SCTPAssociation* SCTPSocket::findAssociationForDestinationAddress(
+   SCTPAssociation* findAssociationForDestinationAddress(
                        multimap<unsigned int, SCTPAssociation*>& list,
                        const SocketAddress** destinationAddressList);
 
Only in socketapi-1.7.0/socketapi: sctpsocket.h~



Archive powered by MHonArc 2.6.19+.

Top of page