[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: One socket per AF (Was: 6to4 using ::FFFF:0000:0000/96...)



On 28 jan 2008, at 14:50, Jeroen Massar wrote:

Jeroen, I'm not quoting your message, because it doesn't make any sense to me.

What I was saying is that it's important to be able to do this, which I've lifted from the getnameinfo() and getaddrinfo() socket call manpages on my Mac with some minimal changes. This tries to set up a TCP session towards port 80 on www.kame.net, cycles through all available addresses and prints those when trying. The same code will do the same thing over IPv4 or IPv6, depending on A/AAAA records and local connectivity. Using this type of code of course does NOT mean that IPv6 packets with ::ffff:x.x.x.x addresses are either sent or received, those can/should be filtered.

For those not skilled in the art of C programming: note how cumbersome it is to do even simple stuff.

#include <stdio.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>

main()
{
 struct addrinfo hints, *res, *res0;
 int error;
 int s;
 const char *cause = NULL;
           char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];

 memset(&hints, 0, sizeof(hints));
 hints.ai_family = PF_UNSPEC;
 hints.ai_socktype = SOCK_STREAM;
 error = getaddrinfo("www.kame.net", "http", &hints, &res0);
 if (error) {
         errx(1, "%s", gai_strerror(error));
         /*NOTREACHED*/
 }
 s = -1;
 for (res = res0; res; res = res->ai_next) {
         s = socket(res->ai_family, res->ai_socktype,
             res->ai_protocol);
         if (s < 0) {
                 cause = "socket";
                 continue;
         }

if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf), sbuf,
               sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV)) {
                   errx(1, "could not get numeric hostname");
                   /*NOTREACHED*/
           }
           printf("host=%s, serv=%s\n", hbuf, sbuf);

         if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
                 cause = "connect";
                 close(s);
                 s = -1;
                 continue;
         }

         break;  /* okay we got one */
 }
 if (s < 0) {
         err(1, "%s", cause);
         /*NOTREACHED*/
 }
 freeaddrinfo(res0);
}