Subject: IPv6 Issues

IPv6 Issues

From: codemastr <codemstr_at_ptd.net>
Date: 2005-04-10

For the most part, IPv6 support seems to be coming along rather nicely. I'm
starting to begin work on the "addrinfo" (getaddrinfo/getnameinfo) API now,
seeing as how, at least in my tests, the current functions work pretty well
with IPv6.

Anyway, there are still some issues that need to be discussed:

1.) Is inet_net_pton.h the proper place for the in6_addr and friends
compatibility stuff? This seems illogical to me. There will be files that
need in6_addr but do not need inet_net_pton.h. For example, I'm currently
working on ares_getnameinfo which will use inet_ntop and has a need for
in6_addr. As far as I can tell,
http://curl.haxx.se/auto/log.cgi?id=20050410193100-25284 is caused by the
fact that this OS does not have in6_addr, and the fact that I am using
in6_addr in ares_private.h results in an error because the structure is not
yet "known." Perhaps a better solution would be to introduce an ipv6.h or
something to that effect?

2.) Does anyone have any suggestions for the API of ares_getnameinfo? The
prototype for the system function is:
int getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host,
size_t hostlen, char *serv, size_t servlen, int flags);
The first thing to note is the use of socklen_t. Not all systems provide
this type which means that ares.h would need even more system-specific
defines, or we could just use int but then it is "incompatible" with the
system getnameinfo.

Second is the buffers. Basically, for those unfamiliar with this function,
you specify a buffer and length for the hostname and the service (port)
name. The function then fills these buffers with the appropriate values
after looking up the contents of sa. For c-ares, I think having
user-supplied buffers is contrary to the way everything else works. Due to
the nature of asynchronous callbacks, c-ares uses library-supplied buffers
which it then passes to the callback function; this is how all the other
functions in c-ares work. Therefore, it seems illogical to have this
function use user-supplied buffers. As a result, I was thinking:

void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa,
socklen_t salen, int flags, ares_nameinfo_callback callback, void *arg);

This models the syntax of the other functions c-ares provides. However,
there is one hitch here. getnameinfo uses the host/serv parameters to
determine what to return. For example, if I specify NULL as serv, then it
means that I only want a host and therefore no service lookup is done.
However, since ares_getnameinfo does not require the user to specify
buffers, this can't be handled the same way. Does anyone have any
suggestions as to how we could handle this? Perhaps we should introduce two
new flags? NI_ARES_HOSTLOOKUP and NI_ARES_SERVICELOOKUP?

3.) The getnameinfo function has several extensions. I think it would be a
good idea to support as many of these as possible as it makes switching to
c-ares easier. There are two such extensions I've found so far that are
implemented on some OSes, one allows the possibility of more than just
UDP/TCP service name lookups (for example, the new SCTP and DCCP protocols),
and the other allows support for scope IDs. The former is very simple to
implement. Basically, they (rightfully) make the argument that IPPROTO_TCP
!= SOCK_STREAM and IPPROTO_UDP != SOCK_DGRAM, other protocols can use the
socket types. Therefore, they introduce some flags such as NI_UDP, NI_SCTP
and so forth. This should be very easy to implement. The latter is also
pretty easy, we just add an NI_WITHSCOPEID and NI_NUMERICSCOPE and call the
appropriate functions to lookup the scope ids.

The problems come in when looked at in light of the fact that these rely on
OS specific features. To lookup a service name, we use the getservbyport
function. Most OSes have no support for SCTP/DCCP. Therefore, a call with
"sctp" specified will most likely always fail. It won't result in any error
condition, but it will mean that the call will result in no lookup taking
place on many systems. So on some systems it will work, on some it will not.

The problem is a bit worse with scope ids. The sockaddr_in6 structure seems
to have a very ambiguous definition. Two members of this structure seem to
be particularly suspect, sin6_len and sin6_scope_id. The latter is the
member that would hold the scope information needed for NI_WITHSCOPEID.
Furthermore, looking up interfaces is not exactly standard either. According
to RFC3493 (the same one that defines the addrinfo stuff), there is a new
function, if_indextoname that we would use to resolve this information. Not
all systems have this function. So there are two implementation issues here.
1.) Does the system even have a sin6_scope_id? and 2.) Does it have
if_indextoname? Making autoconf checks for both of these is very easy, but
the issue becomes cross-OS support. On some OSes, NI_WITHSCOPEID will work
great, on others it won't be able to resolve it to a name and will instead
return the numeric form. Basically, the problem is that depending on which
OS you're using c-ares you might get different results from a call to the
function. If that's OK, then I'll go ahead and add support for it. If not,
then we need to decide what to do.

References:
http://www.ietf.org/internet-drafts/draft-itojun-ipv6-getnameinfo-multiproto-02.txt
http://www.watersprings.org/pub/id/draft-ietf-ipngwg-scopedaddr-format-02.txt

4.) How do we want to handle all the checks for NI_* (and AI_*)? There are
like 20-30 constants defined by getnameinfo and getaddrinfo that we'll need
to check for. Do you think it is a good idea to add that many new autoconf
checks just to determine if the macros exist?

5.) We still need to decide a way to return error codes. Do we want to
implement equivalents to the various RFC3493 defined codes, or do we want to
just have a catch-all "bad argument" code?

Hopefully we can get all these things worked out!

Dominick Meglio

_______________________________________________
http://cool.haxx.se/mailman/listinfo/c-ares
Received on Sun Apr 10 20:48:47 2005