>> yes, the implementation differences are painful for application
>> developers, however, implementers failed to reach the consensus
>> after a long long holy war. the safest way for application
>> implementers is to avoid using IPv4 mapped address at all and use
>> AF_INET6/AF_INET sockets separately.
>Data point for information:
>You cannot at present do that on all OS, as I found when sorting this
>out for Exim.
(assuming that you are talking about the listener side) if you ignore
errors from bind(2) you should be able to do this. On Solaris/OpenBSD/
FreeBSD/whatever, you will open two sockets with the code. On Linux,
you will open AF_INET6 socket only (and you will grab both IPv4 and
IPv6 traffic).
itojun
struct addrinfo hints, *res, *res0;
int sock[MAXSOCK], nsock;
/* grab list of addresses by getaddrinfo */
memset(&hints, 0, sizeof(hints));
hints.ai_socktype = SOCK_STREAM;
hints.ai_family = PF_UNSPEC;
hints.ai_flags = AI_PASSIVE;
getaddrinfo(NULL, "smtp", &hints, &res0);
nsock = 0;
for (res = res0; res; res = res->ai_next) {
sock[nsock] = socket(res->ai_family, res->ai_socktype,
res->ai_aprotocol);
if (sock[nsock] < 0)
continue;
if (bind(sock[nsock], res->ai_addr, res->ai_addrlen) < 0) {
close(sock[nsock]);
continue;
}
nsock++;
break;
}
if (nsock == 0)
/* no socket ready for listening */