[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);
}