To:
Philip Hazel <ph10@cus.cam.ac.uk>
Cc:
dnsop@cafax.se
From:
itojun@iijlab.net
Date:
Thu, 20 Sep 2001 19:05:59 +0900
In-reply-to:
ph10's message of Thu, 20 Sep 2001 09:11:04 +0100. <Pine.SOL.4.33.0109200903120.20149-100000@virgo.cus.cam.ac.uk>
Sender:
owner-dnsop@cafax.se
Subject:
Re: operationally (if not yet WG) related
>> 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 */