Subject: sockets APIs extensions for Host Identity Protocol

From: Miika Komu <[email-masked]>
Date: Fri, 4 May 2007 18:28:30 +0300 (EEST)

Hi all,

we are contemplating a level of indirection in naming hosts to 
future-proof the Host Identity Protocol (HIP). The proposed sockets API 
extensions use locally-scoped "handles" instead of Host Identity Tags 
(HITs, that is, cryptographically generated IPv6-like addresses). One 
could conceive that such a level of indirection could be used more 
generally outside of HIP, to enable applications to be more compatible 
across IP versions, for instance. What are the benefits and costs that you 
see about migrating the basic socket API calls towards end-system handles 
rather than explicit end-system addresses?

A potential benefit of the handles is that it would make the API 
future-proof againts changes to the HIT size. Similarly, one might argue 
that the IPv6 transition would have been a lot easier for applications if 
the concept of endpoint descriptor were already available for the past 
twenty years; IPv6 could have been hidden in the system.  This latter 
observation makes me wonder whether there have been such considerations 
previously in the applications area?

The sockets API extensions are defined here:

http://www.ietf.org/internet-drafts/draft-ietf-hip-native-api-01.txt

-- 
Miika & Tom

---

From: Stephane Bortzmeyer <[email-masked]>
Date: Mon, 7 May 2007 10:27:37 +0200

On Fri, May 04, 2007 at 06:28:30PM +0300,
 Miika Komu <[email-masked]> wrote 
 a message of 27 lines which said:

> One could conceive that such a level of indirection could be used
> more generally outside of HIP, to enable applications to be more
> compatible across IP versions, for instance.

One important thing: this is only for the C programming language. In
most (all?) other languages, programmers no longer handle directly IP
addresses and thus are shielded from things like IPv4 vs. IPv6 or
addresses vs. handles.

> This latter observation makes me wonder whether there have been such
> considerations previously in the applications area?

The big advice should be: use a high-level language (or, in C, a
high-level library, like Neon - http://www.webdav.org/neon/ - or cURL
- http://curl.haxx.se/) and you're safe from the changes in IETF
fashions.

---

From: Chris Newman <[email-masked]>
Date: Mon, 07 May 2007 14:31:31 -0700

Speaking as a technical participant, not as an area director...

Application software wants to work with strings.  When I want to make a network 
connection, I have a string which says what I want to connect to.  It might be 
a DNS name, an IPv4 address literal, and IPv6 address literal, the field after 
the "//" in a URL or whatever the string format for a HIP endpoint is going to 
be.  As an application developer I don't want to care what that string means. 
I might want a way to turn that string into an opaque object (or objects) and 
back (with a timeout) and then use that opaque object in something equivalent 
to connect and/or bind.

I also want a way to enumerate the string representations of the local 
interfaces on a server so that I can offer the administrator a choice of which 
interface(s) the listen ports bind to.  I don't want to care whether those are 
IPv4, IPv6 or HIP or something else.

The only reason I might care what the string or opaque object refers to is for 
debugging/logging/diagnostic purposes.

If I change my "connectbyname" code again, I will change it once more to use a 
new OS API that hides all the v4 vs. v6 vs. HIP vs. whatever junk, preferably 
to something much simpler than the code today.  If such an API isn't produced, 
I will be very reluctant to change that code no matter how cool HIP might or 
might not be.

So the API described in your document is one I plan to never use if at all 
possible.  That might have consequences for HIP deployment, just as the present 
state of IPv6 C socket APIs has not been great for IPv6 deployment.

                - Chris

Miika Komu wrote on 5/4/07 18:28 +0300:

> Hi all,
>
> we are contemplating a level of indirection in naming hosts to future-proof
> the Host Identity Protocol (HIP). The proposed sockets API extensions use
> locally-scoped "handles" instead of Host Identity Tags (HITs, that is,
> cryptographically generated IPv6-like addresses). One could conceive that
> such a level of indirection could be used more generally outside of HIP, to
> enable applications to be more compatible across IP versions, for instance.
> What are the benefits and costs that you see about migrating the basic socket
> API calls towards end-system handles rather than explicit end-system
> addresses?
>
> A potential benefit of the handles is that it would make the API future-proof
> againts changes to the HIT size. Similarly, one might argue that the IPv6
> transition would have been a lot easier for applications if the concept of
> endpoint descriptor were already available for the past twenty years; IPv6
> could have been hidden in the system.  This latter observation makes me
> wonder whether there have been such considerations previously in the
> applications area?
>

---

From: der Mouse <[email-masked]>
Date: Mon, 7 May 2007 18:07:14 -0400 (EDT)

> Application software wants to work with strings.  [...]

> If I change my "connectbyname" code again, I will change it once more
> to use a new OS API that hides all the v4 vs. v6 vs. HIP vs. whatever
> junk, preferably to something much simpler than the code today.

Something wrong with getaddrinfo()?  It certainly could use something
HIPish under the hood, if some implementor decided to.

>> future-proof againts changes to the HIT size.

getaddrinfo() already is...or at least, it is when used correctly, and
in this respect it's easier to use it correctly than incorrecetly
(which is about all you can expect).  It's a slightly broken API, true,
but the problems with it are not in areas that any putative HIP/HIT
stuff would fix.

>> Similarly, one might argue that the IPv6 transition would have been
>> a lot easier for applications if the concept of endpoint descriptor
>> were already available for the past twenty years;

That concept *has* been available for the past twenty years; it's
called a "socket".  What hasn't been available is a socket
implementation that doesn't expose the underlying addressing details to
the application.  This could be - and arguably should be - fixed
entirely under the socket-layer hood, not by inventing new protocols
and exposing *them* to the application.  I speculate that the major
reason this hasn't been done is tradition - sockets have traditionally
been a fairly direct interface into the kernel, and preserving that
while presenting this kind of socket interface is relatively hard.

/~\ The ASCII				der Mouse
\ / Ribbon Campaign
 X  Against HTML	       [email-masked]
/ \ Email!	     7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B

---

From: Keith Moore <[email-masked]>
Date: Tue, 08 May 2007 23:19:51 -0400

> addresses and thus are shielded from things like IPv4 vs. IPv6 or

In those cases, the programmers are also crippled and prevented from
dealing effectively with various cases that are now increasingly common
in the Intenet today: NATs,  multiple addresses for source and
destination (not all of which work equally well), IPv4 vs IPv6 (for
which the default address selection rules are woefully inadequate),
multi-faced DNS, LLMNR, etc.
> - http://curl.haxx.se/) and you're safe from the changes in IETF

only if you want to limit the deployability and/or efficiency of your
application.

Keith

---

From: Keith Moore <[email-masked]>
Date: Tue, 08 May 2007 23:22:37 -0400

> junk, preferably to something much simpler than the code today.  If
> such an API isn't produced, I will be very reluctant to change that
> code no matter how cool HIP might or might not be.

If you can figure out how to write that kind of code in a way that works
well for a wide variety of applications, with different requirements for
bandwidth, stability, mobility, etc. all of which affect address
selection, interface selection, etc., and do all of that efficiently and
in the absence of routing information from the network, you should
probably get a prize of some sort.

Granted that programmers want a simple interface, but the more complex
the network gets, the more apps will be expected to do jobs that were
supposed to be done at layer 3.

Keith

---

From: Keith Moore <[email-masked]>
Date: Tue, 08 May 2007 23:24:35 -0400

> HIPish under the hood, if some implementor decided to.

getaddrinfo() is a disaster.  not only is it the most baroque call in
the entire sockets API, it also invites implementors to abuse its
semantics in numerous ways (for instance, looking up SRV records for
apps that weren't intended to use SRV records).

Keith

---

From: Stephane Bortzmeyer <[email-masked]>
Date: Wed, 9 May 2007 14:17:03 +0200

On Tue, May 08, 2007 at 11:19:51PM -0400,
 Keith Moore <[email-masked]> wrote 
 a message of 29 lines which said:

> dealing effectively with various cases that are now increasingly
> common in the Intenet today: NATs, multiple addresses for source and

I strongly object to the idea of application programmers dealing with
NAT, IPv4 vs. IPv6 or source address selection for the eternity. The
wiring of level-3 details in the applications is precisely what makes
the transition to IPv6 so difficult. Applications should not have to
be "ported to IPv6". They should work the same with both level-3
protocols (and, indeed, they do, in every language but C).

If the IPv6 problems are to be useful, it is in showing that there is
ZERO probability of splitting the identifier and the locator if we
have to change the applications.

I also really doubt that the typical application programmer is able to
do a better job than the kernel / libraries to, choose the source
address or other level-3 features. Plus, IMHO, if someone must
influence this selection, it should be the system and network
administrator, not the application programmer.

> only if you want to limit the deployability and/or efficiency of
> your application.

As an user, I would be very afraid of an application which tries to
play tricks with NAT...

---

From: Keith Moore <[email-masked]>
Date: Wed, 09 May 2007 09:19:14 -0400

> protocols (and, indeed, they do, in every language but C).

In a sense, I agree with you that we don't want most applications having
to deal with these things, and we certainly don't want to saddle the
application with having to deal with these problems forever.  However, I
do not reach the same conclusion about the API that you appear to reach,
for a few reasons. 

First is that there will always be some applications (such as diagnostic
tools) that need to know more about the network, so it is necessary to
have an API that allows those applications to function.

Second, I don't share the view that many seem to have that applications
in general should be IP version agnostic.  IPv4 with NAT is far too
brain-damaged, and has such limited reach, so there is a strong case to
be made that in some point in the future, many kinds of apps should
operate only under IPv6.   Similarly there is a case to be made for some
legacy apps (e.g. apps that exist mostly to talk to obsolete hardware)
to operate only under IPv4.

Third, while it is well and good to talk about ideals, the notion that
"applications should not have to" deal with these things ignores the
fact that in the current network architecture, applications _do_ have to
deal with these things.  This isn't just a consequence of NATs, but also
of the IPv6 architecture which insists that (for a variety of reasons)
hosts shall have multiple addresses, but fails to provide hosts (and
host stacks) with an effective mechanism for selecting among those
addresses on behalf of applications.   Such selection needs to take a
variety of factors into account, including the communications topology
of the application (is it multiparty or point-to-point?) the
application's need for bandwidth, the likely duration of the
application's association with peers, the ability of the application to
tolerate and recover from changes in IP address, the way that the
different address prefixes are used by the network (ELIAs can be used
differently than globals, and link-locals are certainly used differently
than globals), and so forth.

Fourth, for a variety of reasons, DNS names are not and have never been
adequate as general purpose endpoint identifiers, and this situation is
getting worse rather than better.  One reason is that DNS names are not
equivalent to host names, and emphatically not equivalent to
distinguished host names, and haven't been so at least since the web
came into existence.  A given DNS name might be bound to a single host,
multiple hosts having more-or-less equivalent function, a service, a
community of users, or whatever; the binding might be stable or
ephemeral; and the name might or might not be suitable as a
distinguished name (one chosen preferentially over others for use in
indicating that host, group of hosts, service, whatever).  There's no
way to tell.  Another reason is that DNS is often slow and unreliable
and/or out of sync with reality - one of many factors making DNS names
less suitable for referrals between hosts.  Another reason is that
multi-faced DNS limits the visibility of DNS names even when
applications are expected to work across the boundary.  Another reason
is that DNS is increasingly polluted.  For instance, my ISP's default
DNS servers lie about DNS results for domains that have no A records,
even if there are other records in that domain, in order to redirect
HTTP requests for misspelled DNS names to a web server that will
"helpfully" offer links to alternatives (and also display
advertisements).  So however noble it might be to try to present apps
with a simple interface based on DNS names, what this really does is to
cripple apps' ability to cope with the mess that is DNS.

Fifth, trying to overload so many functions in a single API inevitably
masks error conditions that often need to be distinguished, and treated
differently, by the application. 

As for the notion that applications work the same for both v4 and v6 in
every language but C: This goes a long way toward explaining why network
applications continue to be written in C.  And that in turn goes a long
way toward explaining why network applications are notoriously
insecure.  I know that every time I've considered writing a network
application in a new language, I take a look at the network API and
conclude that it's inadequate.  (granted, I tend to write more esoteric
applications)
> have to change the applications.
Despite the oft-cited ideal of splitting the identifier and the locator,
nobody has ever to my knowledge provided a complete and convincing
example of how it can be made to work well.   Actually providing those
identifiers, along with a scalable, reliable, fast, and secure service
that maintains identifier-to-locator bindings is a nontrivial problem
that tends to be overlooked.
> administrator, not the application programmer.
Partially disagree, because the selection is heavily dependent on the
type of application and how it uses the network.  I do think that the
network admin has a role in explaining to the application or API how
particular addresses are to be used, but I don't think it flies to
expect every application to use those addresses in exactly the same
way.  There's a big difference in how you want to handle address
selection for a mounted remote file system than in how you want to
handle address selection in an email MTA.
> As an user, I would be very afraid of an application which tries to
I guess you wouldn't use Skype then, preferring to spend lots of money
on international phone calls.

In my experience users tend to prefer applications that work reliably
over applications that don't work reliably.   Given two apps, one that
copes with NAT and another that doesn't, users will use the one that
copes and blame the one that doesn't - even though arguably the failure
of the latter app is the fault of the network.

Keith

---

From: Keith Moore <[email-masked]>
Date: Wed, 09 May 2007 10:23:08 -0400

>> way to tell.
> All of this is true for IP addresses as well.
>   

good point.  though if you collect multiple hosts under the same IP
address, without considering how this will affect the apps that run on
those hosts, you pretty much deserve to lose. 

neither DNS names nor IP addresses work very well as endpoint identifiers.

Keith

---

From: der Mouse <[email-masked]>
Date: Wed, 9 May 2007 13:21:45 -0400 (EDT)

> NAT, IPv4 vs. IPv6 or source address selection for the eternity.

I object to their having to deal with those issues.  I also object to
their being prevented from dealing with them, even if only because of
diagnostic applications.

> Applications should not have to be "ported to IPv6".

Diagnostic applications aside, I mostly agree.

> They should work the same with both level-3 protocols (and, indeed,
> they do, in every language but C).

Oh, nonsense.  Not every non-C language encapsulates those details
sufficiently to keep applications away from them.  I've seen perl code,
for example, that does pack() and unpack() to construct memory blobs
equivalent to structs sockaddr_in (and which thus needs to be changed
to do likewise for sockaddr_in6, to be v6-ready).

> I also really doubt that the typical application programmer is able
> to do a better job than the kernel / libraries to, choose the source
> address or other level-3 features.

The typical application programmer, perhaps.  But there certainly are
application programmers cokmpetent to manage such details.

> Plus, IMHO, if someone must influence this selection, it should be
> the system and network administrator, not the application programmer.

Sometimes it has to be the application coder, as creator of the user's
proxy to the network.  Some applications are suitable for hiding the
network's complexity, true, but some aren't.

/~\ The ASCII				der Mouse
\ / Ribbon Campaign

---

From: Stephane Bortzmeyer <[email-masked]>
Date: Wed, 9 May 2007 21:43:09 +0200

On Wed, May 09, 2007 at 09:19:14AM -0400,
 Keith Moore <[email-masked]> wrote 
 a message of 129 lines which said:

> First is that there will always be some applications (such as
> diagnostic tools) that need to know more about the network, so it is
> necessary to have an API that allows those applications to function.

We all (I believe) agree that we need a low-level API, mostly, as you
said, for debugging / monitoring / teaching purposes and for some
optimizations in very specific applications.

But this is not the point to discuss since we *already* have this API,
the sockets API, and it works.

What we discuss is a *new* API, a high-level one, not meant to replace
the low-level one for *everything* but for most applications.
 
> Fourth, for a variety of reasons, DNS names are not and have never
> been adequate as general purpose endpoint identifiers,

This is a sensible explanation but, if we agree with it, it only means
that we rule out DNS for the identification of the new high-level
"connection objects". This does not mean that the whole idea of a
high-level API is wrong.

> I guess you wouldn't use Skype then, 

Right.

> preferring to spend lots of money on international phone calls.

I use email. I may switch to SIP or Jabber. I did not find a RFC
describing Skype.

---

From: Stephane Bortzmeyer <[email-masked]>
Date: Wed, 9 May 2007 21:53:19 +0200

On Wed, May 09, 2007 at 01:21:45PM -0400,
 der Mouse <[email-masked]> wrote 
 a message of 38 lines which said:

> > They should work the same with both level-3 protocols (and,
> > indeed, they do, in every language but C).
> 
> Oh, nonsense.  

Simple exaggeration.

> Not every non-C language encapsulates those details sufficiently to
> keep applications away from them.  I've seen perl code,

OK, OK, not all languages are better than C in that respect. But I do
not want to mention only Java, as some people keep repeating. Many
languages offer a similar high-level API (Python, Lua, Haskell, Ruby,
...).

---

From: Keith Moore <[email-masked]>
Date: Thu, 10 May 2007 11:06:28 -0400

> the sockets API, and it works.
the sockets API is not sufficient even as a low-level API.  we're going
to need extensions to both network protocols and the sockets API to
function effectively in a world where hosts have multiple addresses and
it matters which address you use.
> the low-level one for *everything* but for most applications.
we do need a high-level API, but such an API still needs to be able to
accept application preferences and requirements for that particular socket.

I generally find that assumptions about "most applications" turn out to
be wrong - if not in the present, than in the in the near future.
> "connection objects". This does not mean that the whole idea of a
the idea is fine, but the devil is in the implementation details.  it's
easy to design a high-level API that works for a limited number of
cases, very difficult to make one that works well in practice for
everyone in the diversity of the Internet.
> I use email. I may switch to SIP or Jabber. I did not find a RFC
I'm quite willing to learn lessons from their example even if they don't
document their protocol in an RFC.

Keith

---

From: Miika Komu <[email-masked]>
Date: Thu, 10 May 2007 21:40:05 +0300 (EEST)

On Wed, 9 May 2007, Keith Moore wrote:

Hi,

> neither DNS names nor IP addresses work very well as endpoint identifiers.

thanks for the good points! However, it is not still clear to me what to 
do in the case of HIP aware applications. I hope we can agree that 
something needs to be done at the sockets API layer? At the minimum, we 
want to make the application to use HIP (either by using HITs directly or 
indirectly through locally-scoped identifiers), and provide a way for the 
application to determine that it is using HIP.

My exact question is that what to put into the socket address structures 
when we have HIP-aware applications. Based on the discussion, I think we 
can leave socket address structures based on DNS names out of the scope 
and concentrate on two alternatives: globally scoped HITs and locally 
scoped idenfiers (endpoint descriptors).

The use of globally-scoped HITs has the following trade-offs:
+ No extra translation step from local id to global id
+ Smaller transition step to convert a legacy app to a HIP aware app?
- Opportunistic HIP mode, where the server's HIT is not known before hand,
   will require a locally-scoped identifier anyway. This is similar to
   IN6ADDR_ANY, but it is used for the remote host, i.e.,
   connect(UNKOWN_HIT) where only the locator is known.
- No future proofing against the HIT size

Locally-scoped identifiers have the reverse properties:
- Extra translation step from local id to global id
- Bigger transition step to convert a legacy app to a HIP aware app?
+ All identifiers are of the same type (also in opportunistic HIP mode)
+ Future proofing against changes in the HIT size

If you had to choose between these two, what would you choose and why? 
Do the proposed trade-offs make sense and would have something to add?

P.S. Please notice that the HITs are basically "free" of the NAT burden 
because they are globally scoped, end-to-end identifiers.

-- 
Miika Komu                                       http://www.iki.fi/miika/

---

From: "Henderson, Thomas R" <[email-masked]>
Date: Tue, 8 May 2007 09:43:45 -0700

> -----Original Message-----
> From: Chris Newman [mailto:[email-masked]] 
> Sent: Monday, May 07, 2007 2:32 PM
> To: Miika Komu; [email-masked]
> Cc: Henderson, Thomas R
> Subject: Re: sockets APIs extensions for Host Identity Protocol
> 

Chris, 
Is the IETF in the business of defining this new API?  Or is the IETF
scope limited to sockets, and the APIs that you seek are defined by
library and OS developers?

As a HIP WG participant, I see that there has been a history of RFCs for
sockets API extensions (2292, 2960, 4584, etc.).  We could do a similar
one for HIP, but Miika has proposed that we go for a more future-proof
API and build in some abstraction.  It seems to me that there is support
for defining such an API and it has already been done successfully for
Java.

(note also that there has been discussion on the RAM list this week on
this topic).

Tom

---

From: Miika Komu <[email-masked]>
Date: Wed, 9 May 2007 00:38:24 +0300 (EEST)

On Mon, 7 May 2007, Stephane Bortzmeyer wrote:

Hi Stephane and thanks for your comments,

> addresses and thus are shielded from things like IPv4 vs. IPv6 or

Yes, that is true.

> - http://curl.haxx.se/) and you're safe from the changes in IETF

The higher-level languages are always based on the C-language sockets API. 
Would it make sense to make the modification to a single place (sockets 
API) rather than all of the present programming language implementations? 
The latter is, of course, better than modifying all applications.

---

From: Miika Komu <[email-masked]>
Date: Wed, 9 May 2007 01:21:07 +0300 (EEST)

On Mon, 7 May 2007, der Mouse wrote:

Hi and thanks for you comments,

> HIPish under the hood, if some implementor decided to.

Yes, I think the changes in the native HIP API draft are not visible at 
all to higher-level "connectbyname" callers. However, the C-based sockets 
API is used by all of the higher-level libraries and languages...

> but the problems with it are not in areas that any putative HIP/HIT

I am curious. Even though this is irrelevant for the discussion, can be 
more specific on what is broken with getaddrinfo?

> while presenting this kind of socket interface is relatively hard.

Yes, I agree that the socket would do the trick and would provide enough 
indirection. As you said, the problem is with the tradition of exposing 
the addresses directly to the application. To solve this problem properly, 
we need a "clean slate" approach for the APIs. However, I am not sure if 
the sockets API level is proper place to do this. The draft tries to 
preserve backwards compability while extending the current sockets API to 
its limits. The backwards compatibility is handy when porting old sockets 
API based applications to use the API. The limits are reached by hiding 
the presentation of identifiers and port numbers behind endpoint 
descriptors.

I am not sure what you meant with protocol, but here I assume you meant 
PF_SHIM. The new PF_SHIM family was "invented" as a consequence of 
introducing a new socket address structure for endpoint descriptors. This 
way, the correct size of the socket structure can be determined. It also 
makes more sense to have a separate socket handler for endpoint 
descriptors rather than to mix with IPv4 or IPv6 sockets handlers.

---

From: Miika Komu <[email-masked]>
Date: Wed, 9 May 2007 10:52:45 +0300 (EEST)

On Tue, 8 May 2007, Keith Moore wrote:

Hi,

> multi-faced DNS, LLMNR, etc.

Yes, we need both simple and advanced interfaces and let the 
application developer choose what ever that is required for the 
application. This considers especially multihoming:

http://www.ietf.org/internet-drafts/draft-ietf-shim6-multihome-shim-api-02.txt

For the NAT traversal, my opinion is that we should should avoid making 
the applications NAT aware because would just too much unnecessarily 
redundant code around. This is approach taken in the NAT traversal draft 
(beware, the protocol mechanism is going to change in the next version 
radically):

http://www.ietf.org/internet-drafts/draft-ietf-hip-nat-traversal-01.txt

---

From: Tony Finch <[email-masked]>
Date: Wed, 9 May 2007 14:50:31 +0100

Tony.
-- 
f.a.n.finch  <[email-masked]>  http://dotat.at/
NORTH FITZROY SOLE: SOUTHWESTERLY 6 TO GALE 8. ROUGH OR VERY ROUGH. RAIN OR
DRIZZLE. MODERATE OR POOR.

---

From: Keith Moore <[email-masked]>
Date: Thu, 10 May 2007 14:57:20 -0400

> My exact question is that what to put into the socket address
> structures when we have HIP-aware applications. Based on the
> discussion, I think we can leave socket address structures based on
> DNS names out of the scope and concentrate on two alternatives:
> globally scoped HITs and locally scoped idenfiers (endpoint descriptors).
>
offhand, I think you need to support both.  HITs aren't very useful to
apps unless they are visible to them and globally-scoped.  HIP is still
useful without HIT visibility, but less useful.

---

From: Miika Komu <[email-masked]>
Date: Thu, 10 May 2007 22:04:52 +0300 (EEST)

> useful without HIT visibility, but less useful.

It does not mean that the HIT fingerprint, or preferably even the 
corresponding public key, are completely invisible to the application with 
locally-scoped identifiers. It is just a question of an extra function 
call that translates the local-scope identifier to the desired format (HIT 
or public key).

---

From: Keith Moore <[email-masked]>
Date: Fri, 11 May 2007 01:00:35 -0400

> corresponding public key, are completely invisible to the application
> with locally-scoped identifiers. It is just a question of an extra
> function call that translates the local-scope identifier to the
> desired format (HIT or public key).
It strikes me that if I'm using opportunistic HIP, then I probably want
to use normal sockaddr_in* structures and do a setsockopt() that says
"give me HIP if both ends support it" before doing connect() or
listen().  In that case I'd want getpeername() to still return the
peer's (current) IP address, but I'd want additional functions to return
the peer's HIT.  In that case I don't see any real value in having
locally-scoped pseudo-HITs.  The reason for doing things this way is
that it would require fewer changes to legacy code to support
opportunistic HIP.

OTOH, if I'm doing "real" HIP then I want to use something like a
sockaddr_hip structure that lets me specify both the HIT (as the
"address") and a variable number of IP addresses (including both IPv4
and IPv6 addresses) at which the peer named by the HIT might be
reachable (or at which a redirect to the actual peer might be
obtainable).  And then you probably want a HIP-specific replacement for
getaddrinfo() that will return not only addresses but also the HIT
associated with a DNS name and whatever other information is useful in a
form that's easily stuffed into a sockaddr_hip.

really you want to be able to map a DNS name into multiple HITs, each of
which can have zero or more IPv* addresses associated with it.... and 
you want a standard data structure that consists of a HIT + IP addresses
that can be passed around in referrals.

---

From: Miika Komu <[email-masked]>
Date: Fri, 11 May 2007 09:19:44 +0300 (EEST)

On Fri, 11 May 2007, Keith Moore wrote:

Hi Keith,

> that it would require fewer changes to legacy code to support

We have implemented opportunistic mode in the HIPL implementation in the 
way you described. It required some tricks under the sockets API hood to 
get it working, but it is great for legacy apps. Even referrals work, 
assuming that you are behind a NAT or a firewall :)

What about "native" HIP applications that are aware of HIP? The whole 
point of the locally scoped identifier was to provide single, unified 
end-point token to applications. Is it acceptable to handle both 
sockaddr_in and sockaddr_hip structures in HIP aware apps? I think a 
single identifier type would be simpler.

> obtainable).

The is certainly possible. One could also implement opportunistic mode by 
leaving out the HIT from sockaddr_hip and by specifying only the IP. 
However, there is an inherent problem with this approach as described 
below.

> And then you probably want a HIP-specific replacement for

Why this can't be done in the current resolver by specifying a flag?

> that can be passed around in referrals.

The problem with this approach is that it will encourage developers to use 
the IP address directly from the socket address structure. The host 
corresponding to the HIT may have changed it's IP address at that point 
(independently of whether the structure describes the local or remote 
host). I believe that it is be much better to "force" the developer to 
obtain a valid IP address using a separate function call (see 
draft-ietf-shim6-multihome-shim-api). An extra call should not be a 
problem in a HIP aware application.

---

From: Keith Moore <[email-masked]>
Date: Fri, 11 May 2007 04:12:56 -0400

> We have implemented opportunistic mode in the HIPL implementation in
> the way you described. It required some tricks under the sockets API
> hood to get it working, but it is great for legacy apps. Even
> referrals work, assuming that you are behind a NAT or a firewall :)
in other words, they don't work. :)
> single identifier type would be simpler.
I don't know why a HIP-aware app would use sockaddr_in* for any socket
on which it wanted to use HIP.  Such an app might want to use
sockaddr_in for some sockets if it had a reason to not use HIP on
specific sockets.  (say for diagnostic purposes)

I must have missed the point of locally-scoped identifiers.  I thought
it was so that you could fit a pseudo-HIT into 32 bits and pretend it
was an IPv4 address for the sake of backward compatibility.  But if your
application was written to be HIP-aware, it would be cleaner to use
HIP-specific sockaddrs.    And in that case, why use a locally-scoped
identifier when you can use a globally-scoped one?   (and if your
application wasn't originally written to use HIP it's probably the case
that the best you can hope for with small mods to your code is
opportunistic HIP anyway.)

> The is certainly possible. One could also implement opportunistic mode
> by leaving out the HIT from sockaddr_hip and by specifying only the
> IP. However, there is an inherent problem with this approach as
> described below.
>
for starters, the addrinfo structure doesn't have a field for a HIT, and
in a HIP aware app you'd certainly want to specify which HIT you wanted
to talk to.   neither does addrinfo have any way of representing things
that are quite reasonable - like a single DNS name mapping to multiple
HITs, each of which maps to multiple IP addresses, where some of those
addresses are addresses at which the peer might reasonably be found, and
others are for redirect servers.

more generally, getaddrinfo() sucks so bad that any excuse to get rid of
it is worth considering.
> The problem with this approach is that it will encourage developers to
> use the IP address directly from the socket address structure. The
> host corresponding to the HIT may have changed it's IP address at that
> point (independently of whether the structure describes the local or
> remote host). I believe that it is be much better to "force" the
> developer to obtain a valid IP address using a separate function call
> (see draft-ietf-shim6-multihome-shim-api). An extra call should not be
> a problem in a HIP aware application.
it's certainly the case that DNS-to-HIT mapping might change
independently of a HIT-to-IP mapping.  that, and when there are multiple
HITs associated with a single DNS name, a single routine might end up
doing several different lookups for the HIT-to-IP mappings, which could
take a lot of time.   so on reflection I agree that it makes sense to do
the lookups separately.

---

From: der Mouse <[email-masked]>
Date: Fri, 11 May 2007 09:08:26 -0400 (EDT)

> more generally, getaddrinfo() sucks so bad that any excuse to get rid
> of it is worth considering.

What do you see as wrong with it?  (Not that I disagree; I see it as
having problems too.  But I sure see it as a lot better than forcing
application code to know about all the possible address families - sort
of "the worst interface available except for all the others".  I'm just
interested in what might be wrong with it that I haven't noticed.)

/~\ The ASCII				der Mouse
\ / Ribbon Campaign

---

From: Miika Komu <[email-masked]>
Date: Fri, 11 May 2007 16:19:38 +0300 (EEST)

> specific sockets.  (say for diagnostic purposes)

Sorry, I meant sockaddr_in6 in this case.

> was an IPv4 address for the sake of backward compatibility.

Yes. There can be two types of "pseudo-HITs":

Local Scope Identifier (HIP legacy apps draft):
* Looks like an IPv4 address
* Might even have a locally configured prefix to separate between a LSI
   and non-LSI address

Endpoint descriptor (HIP native apps draft):
* Looks more like a FD (increasing or random number)
* No prefix

> But if your application was written to be HIP-aware, it would be cleaner 
> to use HIP-specific sockaddrs.  And in that case, why use a 
> locally-scoped identifier when you can use a globally-scoped one?  (and 
> if your application wasn't originally written to use HIP it's probably 
> the case that the best you can hope for with small mods to your code is 

Yes, but how to do opportunistic mode in a new application that wants to 
use opportunistic mode for some connections and normal mode for others?

> others are for redirect servers.

The addrinfo structure has the generic sockaddr *ai_addr field which can 
be used for encapsulating a HIT, LSI or ED.

One of reasons for the local-scope identifier was to hide the "which HIT 
maps to which IP" complexity from the application. This does not prevent 
the application rearranging the identifiers behind the locally-scoped
identifiers using a separate function call.

What kind of redirect servers are we talking about?

> more generally, getaddrinfo() sucks so bad that any excuse to get rid of

How would a new resolver work in your opinion? I guess there has not been 
any prior work on this in the IETF.

> take a lot of time.   so on reflection I agree that it makes sense to do

Ok, but what do you think about exposing the IP address to the 
applications in a sockaddr_hip structure? My point was not really about 
the lookup process, but more like what is going to happen after initial 
contact between two hosts. After establishing communications, a host 
moves to another network, detects that its IP address has changed and 
communicates its new location to the peer. At this point, the IP address 
that was originally received from the resolver is depracated.

---

From: Keith Moore <[email-masked]>
Date: Fri, 11 May 2007 10:03:11 -0400

> Sorry, I meant sockaddr_in6 in this case.
the same argument applies.  If I want to specify that I'm connecting to
a HIT, I don't want to use a sockaddr_in6 structure to do that and have
it somehow magically know the difference between a HIT and an IPv6
address.  I want to use a sockaddr_hit structure for that.  That way, I
get a clean separation of layers, with all that that implies - better
ability to distinguish errors from different layers and handle each
appropriately, clearer visibility to the programmer as to what's
happening underneath the API, etc.
> * Looks more like a FD (increasing or random number)
I don't immediately see the purpose of the latter type of pseudo-HIT?  
(guess I should go dig up the draft...)
>> But if your application was written to be HIP-aware, it would be
>> cleaner to use HIP-specific sockaddrs.  And in that case, why use a
>> locally-scoped identifier when you can use a globally-scoped one? 
>> (and if your application wasn't originally written to use HIP it's
>> probably the case that the best you can hope for with small mods to
>> your code is opportunistic HIP anyway.)
>
> Yes, but how to do opportunistic mode in a new application that wants
> to use opportunistic mode for some connections and normal mode for
> others?
well, the setsockopt() mechanism for enabling opportunistic HIP that
would be useful for modifying legacy apps could also be used for new apps.

if you wanted to have a mechanism to do the same thing with
sockaddr_hit, say by setting the HIT field to HIT_UNKNOWN or some such,
that could be defined also.  though the details would be interesting to
work out.
> The addrinfo structure has the generic sockaddr *ai_addr field which
> can be used for encapsulating a HIT, LSI or ED.
ah yes, good point.
> One of reasons for the local-scope identifier was to hide the "which
> HIT maps to which IP" complexity from the application. This does not
> prevent the application rearranging the identifiers behind the
> locally-scoped
at this level of API, hiding the "which HIT maps to which IP" complexity
seems misguided.   let the high-level API do that.  you need an API that
exposes this stuff.
> What kind of redirect servers are we talking about?
I haven't keep track of the HIP discussions on this topic, so I don't
know what they're being called.  but at one time there was an idea that
you could have a server that could be associated with a HIT that would
securely be updated with current IP addresses for that HIT, and which
could securely tell peers of that HIT when the host associated with the
HIT had moved.  (those servers would need to be located at relatively
stable addresses).  you'd want to be able to discover those servers
through DNS or a similar mechanism.
> How would a new resolver work in your opinion? I guess there has not
> been any prior work on this in the IETF.
it will take more than an email message to answer that question.
> applications in a sockaddr_hip structure? My point was not really
> about the lookup process, but more like what is going to happen after
> initial contact between two hosts. After establishing communications,
> a host moves to another network, detects that its IP address has
> changed and communicates its new location to the peer. At this point,
> the IP address that was originally received from the resolver is
> depracated.
we're a very long way from being able to trust a kernel to make
effective address selection across a wide variety of network
environments and application requirements.  until we get there, the
addresses need to be exposed to the application, and the application
needs to be able to specify which addresses are allowed to be used.  if
nothing else, you're going to need that for diagnostics.  if some user
tells his sysadmin that his program can't connect to HIT xxxx, the
sysadmin has no way to know how to debug the problem.  if instead the
message is "cannot connect to HIT xxxx at address yyyy", a traceroute to
yyyy might yield some useful information.

granted, however, that the sockaddr_hit structure can only communicate
the IP addresses at which the peer with that HIT might initially be
found.   once the connection is established, all assumptions about the
HIT-to-IP bindings that were established in sockaddr_hit are invalid.

Keith

---

From: Keith Moore <[email-masked]>
Date: Fri, 11 May 2007 10:51:57 -0400

> interested in what might be wrong with it that I haven't noticed.)
I suspect I could write an RFC about what's wrong with getaddrinfo().

the nice thing about it is that it does two things for you.  one is that
it completely initializes sockaddr structures for you.   the other is
that (at least in recent versions?) it can take either a DNS name or an
address literal and do the right thing with it.  so if you want to use
that name or literal to initialize a sockaddr to open up a connection,
it can do that.

in a nutshell, the downsides are these (note, this is probably not a
complete list, just what's off the top of my head):

- it's actually more difficult to set the parameters for getaddrinfo()
to get it to do what you want, than it is to initialize the fields in a
sockaddr_in*

- getaddrinfo encourages use of string constants to specify ports,
rather than numeric constants, which is wrong -  it adds an extra layer
of indirection that can (and does) fail, and it tempts people to try to
use that layer of indirection to do things that violate protocol
specifications (like do a SRV lookup for protocols that aren't specified
to use SRV) or otherwise try to be too clever. for instance, I've seen
an implementation of getaddrinfo fail when given a numeric string
constant for the port, because that port couldn't be found in /etc/services.

- it has no way to be used asynchronously other than to put each call to
getaddrinfo in a separate thread, and even then, many implementations
are not thread-safe.

- it's not specified to use DNS.   so if a protocol is specified to use
DNS in some particular way, and the implementation of the protocol uses
getaddrinfo(), the implementation may fail to strictly follow the
protocol spec.  (yes, this is propagating an error that was present in
gethostbyname(), but getaddrinfo() missed the opportunity to fix it. 
some implementations do have a flag that insists that DNS be used)

- the handling of v4 vs v6 vs mapped v4 addresses is confusing.

 - it can lookup address literals but you still need to set the
AI_NUMERICHOST bit in the flags if the name field is an address literal,
if you want the code to work portably.  so in the common case where
you're passed a string that could either be a name or an address
literal, you still have to parse that string to determine whether it's
an address in order to know how to set that bit.  the default should be
to accept either a DNS name or address literal.  there could still be
options that would cause it to fail if the name parameter weren't a DNS
name or address literal.

- similarly for AI_NUMERICPORT for implementations that support that flag

- various platforms shipped with getaddrinfo() implementations based on
early specifications, so there's a fair amount of variation from one
platform to another in what features are actually supported.  it can be
a challenge to write portable code that uses it.

- address ordering often produces suboptimal results.  arguably this is
not the fault of getaddrinfo() except that it creates the expectation
that the API or kernel can do a good job of address ordering.

---

From: Miika Komu <[email-masked]>
Date: Fri, 11 May 2007 18:26:29 +0300 (EEST)

> happening underneath the API, etc.

Ok. Would you be fine with having a new address family (AF_HIP) to 
separate between sockaddr_hip and sockaddr_in6?

> (guess I should go dig up the draft...)

I don't see any reason to give HIP aware applications LSIs that 
look like IPv4 addresses but are actually presenting HITs. Here's also a 
couple of short slide sets:

http://www3.ietf.org/proceedings/05aug/slides/apparea-3.pdf
http://www3.ietf.org/proceedings/06jul/slides/hip-2.pdf

And some future research extensions for the endpoint descriptors:

http://kathrin.dagstuhl.de/files/Materials/06/06441/06441.KomuMiika.Abstract.txt
http://kathrin.dagstuhl.de/files/Materials/06/06441/06441.KomuMiika.Slides.pdf

> that could be defined also.  though the details would be interesting to

Ok.

Right.

> through DNS or a similar mechanism.

I think you are talking about rendezvous server that are similar to the 
home agents in MobileIP.

> HIT-to-IP bindings that were established in sockaddr_hit are invalid.

Are you fine with a sockaddr_hit structure that contains only the HIT and 
letting a getsockopt() call to figure out the IP addresses in the context 
of HIP aware applications? (I think getsockname and getpeername should 
return the HITs.)

---

From: der Mouse <[email-masked]>
Date: Fri, 11 May 2007 12:02:00 -0400 (EDT)

>> What do you see as wrong with [getaddrinfo()]?
> the nice thing about it is that it does two things for you.  one is
> that it completely initializes sockaddr structures for you.   the
> other is that (at least in recent versions?) it can take either a DNS
> name or an address literal and do the right thing with it.

The major thing *I* use it for is to insulate the application from
knowledge of what address families are available.  If correctly written
(getaddrinfo() can be used wrong, as most things can), an application
can be totally new-AF-ready.  If I write an SMTP client with
getaddrinfo() and then, a year later, someone defines SMTP-over-DECnet
(or SMTP-over-IPv7, or whatever), my code will start trying DECnet
without any changes whatsoever to the application.  (If, of course,
it's running on a DECnet-aware - or IPv7-aware - system.)

> - it's actually more difficult to set the parameters for
>    getaddrinfo() to get it to do what you want, than it is to
>    initialize the fields in a sockaddr_in*

Yes, if all you want is AF_INET - or AF_INET6 - it is.  But this is
*not* true if "what you want" is for the app code to be AF-agnostic, as
I sketched above.  I'm not even sure it's true if you want AF_INET
*and* AF_INET6; I find it about evenly balanced whether getaddrinfo()
or doing both INET* AFs is messier, more difficult, whatever.

>    rather than numeric constants, which is wrong -

No, this is very right.  The notion that "ports" are small integers is
a *horribly* IP-centric notion.  DECnet, for example, uses short
strings (8-char? 12-char? I don't know the limit) which do *not* have
to map into numbers - I think X over DECnet, for example, uses "port"
strings like "X$0" and "X$1".

>    it adds an extra layer of indirection that can (and does) fail,
>    and it tempts people to try to use that layer of indirection to do
>    things that violate protocol specifications (like do a SRV lookup
>    for protocols that aren't specified to use SRV)

We must be talking about different getaddrinfo()s.  The one I'm used to
doesn't do anything with SRV records, ever, as far as I can see (I
checked both the manpage and the code).

> - it has no way to be used asynchronously other than to put each call
>    to getaddrinfo in a separate thread,

Neither does gethostbyname().  And, without a lot of callback or AIO
scaffolding - or threading - it *can't*.

> - it's not specified to use DNS.

It's not really specified clearly at all, it appears.  Again, a valid
criticism, but a fixable one.

But it can't really be specified to use DNS, since it is not restricted
to address families that the DNS supports, and it also has to work on
systems not connected to the Internet (/etc/hosts and its ilk).  If I
had to set up a private DNS root just to use host names on an isolated
subnet, I'd call that cripplingly broken.

>    so if a protocol is specified to use DNS in some particular way,
>    and the implementation of the protocol uses getaddrinfo(), the
>    implementation may fail to strictly follow the protocol spec.

This is not a problem with getaddrinfo(); this is a problem with
implementors using inappropriate calls.  getaddrinfo() is not
appropriate for implementing protocols defined must-use-DNS, because of
the above issues.  (I'd actually argue that such specs are broken,
because they mean the protocol is unreasonably difficult to use
according to spec except on the public Internet.)

> - the handling of v4 vs v6 vs mapped v4 addresses is confusing.

No more than v4 vs v6 vs mapped v4 are to begin with.

The rest of your points - including the pieces I cut from the oens I
did address specifically - seem to fall into two categories: "no clear
agreed-upon spec" and "buggy implementations are common".  While these
are fair answers to my question, neither one seems to me like a reason
to ditch the interface entirely when considering standardizing
something for (say) HIP/HIT use.

/~\ The ASCII				der Mouse
\ / Ribbon Campaign

---

From: Keith Moore <[email-masked]>
Date: Fri, 11 May 2007 16:09:26 -0400

> separate between sockaddr_hip and sockaddr_in6?
yes, I think that would be appropriate.
> I don't see any reason to give HIP aware applications LSIs that look
> like IPv4 addresses but are actually presenting HITs. Here's also a

thanks, I'll take a look.
> I think you are talking about rendezvous server that are similar to
> the home agents in MobileIP.
yes, I think that's the term that was being used last time I heard it
mentioned.
> Are you fine with a sockaddr_hit structure that contains only the HIT
> and letting a getsockopt() call to figure out the IP addresses in the
> context of HIP aware applications? (I think getsockname and
> getpeername should return the HITs.) 
if the sockaddr_hit structure contains only the HIT, how is the kernel
going to know where it can contact that peer?  It has to get one or more
IP addresses from somewhere. 

Keith

---

From: Miika Komu <[email-masked]>
Date: Fri, 11 May 2007 23:32:01 +0300 (EEST)

> IP addresses from somewhere.

If the resolver is used, it can send a hint containing this mapping to the 
HIP daemon.

---

From: Miika Komu <[email-masked]>
Date: Fri, 11 May 2007 23:52:22 +0300 (EEST)

> something for (say) HIP/HIT use.

The getaddrinfo may have its shortcomings, but it does not really prevent 
to write HIP bindings for it. As you said, it does handle address family 
independency quite well even though other things might be handled better. 
If there is better interface in the future, we can define HIP bindings 
also for it.

---

From: Keith Moore <[email-masked]>
Date: Fri, 11 May 2007 16:53:43 -0400

der Mouse wrote:
> knowledge of what address families are available.  
that's just fine for some corner cases, and if it works for your app,
great - but it's not the general case.  I like that getaddrinfo() can do
this, but I've found a surprising number of cases where I need to treat
IPv4 and IPv6 addresses differently.   there are several reasons for this:

- one is that the default address selection rules are just broken - or
at least, hopelessly naive.   for example it is nearly always better to
use a native IPv4 (non-private) address in preference to a 6to4 or
Teredo IPv6 address that would require use of a relay router - but
whether it's actually better or not depends on the application and how
it uses addresses (e.g. whether it does referrals). 

- another reason is that an increasing number of ISPs are supplying DNS
servers that lie about the contents of their zone and return bogus A
records for any zone that doesn't have A records - even if the zone does
have other valid records like AAAA records.  those bogus A records point
to http servers that will "helpfully" respond to a request for a web
page with that ( supposedly misspelled) domain and return pointers to
other web sites that might be the right one - along with advertisements
that make money for the ISP.  I've experimented with various kinds of
hacks in order to keep my apps from getting screwed by such ISPs, but
all of them require my app to be aware of address families.

- NATs, private addresses, link-local addresses, LLMNR all complicate
the picture for an app that's trying to work in a variety of
environments.  again, the app needs knowledge of address types in order
to try to sort things out. 
> If correctly written
and the chances that this will actually work correctly are nil, because
every new kind of address family will be subtly different than the old
ones.  for instance, SMTP over DECnet (which does exist, or at least did
exist) imposed a maximum line length of 512 bytes.  to take a more
recent example, SCTP isn't quite a drop-in substitute for TCP even if
both ends support it, because it lacks a clean close and urgent data,
and there are apps that rely on each of these.

again, it's nice that getaddrinfo() gives you a way to pretend that IPv4
and IPv6 are interchangeable for the benefit of the apps that can use
that feature, but it's not as if all apps can or should work that way.
> or doing both INET* AFs is messier, more difficult, whatever.
there are more quirks than that.  you have to know whether you have a
numeric address and port.
> No, this is very right. 
sorry, I've spent way too much time debugging brain-damaged code that
used getservbyname() and which failed when the NIS server went down or
the /etc/services file got corrupted EVEN THOUGH THE PORT TO BE USED WAS
A DEFINED CONSTANT IN THE PROTOCOL SPECIFICATION.   anytime you invoke a
function call that should always, always, always return a constant and
that function can possibly do anything else but return that constant,
you are basically asking for the sack.  and you deserve it.
>  The notion that "ports" are small integers is
> a *horribly* IP-centric notion.
and the vast majority of our protocols are, by definition, IP centric. 
the socket() interface can and has been used for non-IP networking, but
trying to make a name lookup function support the lookup semantics of
every possible future networking technology is just naive.  that kind of
generality almost never ends up being used.   what we need to make IP
applications be robust is a name lookup function that works very well
with DNS and DNS records.
> checked both the manpage and the code).
it's been proposed, more than once, because it seems "obvious" to those
who misunderstand SRV.  part of the problem is, the definition of the
function doesn't actually say what the function does with respect to DNS
because it's too vague - probably as a result of trying to take future
hypothetical networking stacks into account.
> scaffolding - or threading - it *can't*.
I don't think it's quite as bad as you make it out to be.  but I need to
either write one or find an existing example to be sure.
> to address families that the DNS supports
that's a bug, not a feature.
> , and it also has to work on
> systems not connected to the Internet (/etc/hosts and its ilk).  

that's possibly also a bug, not a feature.  too many apps break when
address lookups on different hosts produce inconsistent results.
> If I
no, we'd just have servers that were purpose-built to do that.  or these
days we'd use LLMNR to do that.

unfortunately the details of how to write an app that works well on all
of: the public internet, private networks with some interconnection to
other private networks, and isolated subnets, don't seem to have ever
been worked out - not for name lookup, address selection, automatic host
configuration, or anything else.  so we have a hodgepodge of
half-solutions and no guidance for either software authors or network
operators.
> the above issues.  
well, then getaddrinfo() is not appropriate for a large number of IETF
protocols, because these either explicitly or implicitly expect DNS
(e.g. if DNS is the means by which the protocol engines locate one
another in the absence of explicit agreement, as is the case for SMTP).
> (I'd actually argue that such specs are broken,
IETF tends to define how protocols work on the public Internet, and to
not concern itself quite so much with what happens elsewhere between
consenting adults.   traditionally that's been the right answer, but
nowadays isolated/ad-hoc/private networks and private interconnections
are increasingly common - and we need for apps to be able to run in all
of those environments without changes or special configuration.
> something for (say) HIP/HIT use

I've seen so much variation between implementations of getaddrinfo that
I've become convinced that it needs to be replaced for that reason
alone.  But the variation seems to have resulted from two things: the
vagueness of the spec (in turn the result of overgenerality)  and a
demand to get the interface nailed down before the requirements were
understood.

Keith

---

From: Keith Moore <[email-masked]>
Date: Fri, 11 May 2007 16:58:51 -0400

Miika Komu wrote:
> If the resolver is used, it can send a hint containing this mapping to
> the HIP daemon.

please no.  don't try to hide this stuff from the app in the low-level
API.   the rest of the network keeps trying to force routing decisions
on the apps in the absence of routing information.  ideally, the app
shouldn't have to be doing any routing or address selection or
anything.  but at present, how to cope with this kind of world is an
unsolved problem, and the only place where experimentation can be done
towards learning how to solve that problem is at layer 7.    if you
cripple the API, you prevent that kind of experimentation (at worst) or
(at best) increase the burden on the app writer by forcing him to write
his own kernel extensions.

that, and you still need to expose IP addresses for diagnostic purposes.

what do you gain from trying to hide the IP addresses? 

APIs should not try to be smarter than the apps that use them - they
will always fail at this.  (actually this goes for any kind of middleware)

Keith

---

From: Keith Moore <[email-masked]>
Date: Fri, 11 May 2007 16:59:29 -0400

> The getaddrinfo may have its shortcomings, but it does not really
> prevent to write HIP bindings for it.
clearly it can be done.  but some things do not deserve to live.

---

From: Miika Komu <[email-masked]>
Date: Sat, 12 May 2007 00:18:37 +0300 (EEST)

> what do you gain from trying to hide the IP addresses?

First, to discourage the use of IP addresses as referrals because 
application developer would have to fetch them using a separate function 
call. But maybe this is a weak justification... Second, the socket address 
structure is constrained to 255 bytes. It will fit "only" 1 HIT and 15 
addresses. Is this enough for e.g. routers?

---

From: Keith Moore <[email-masked]>
Date: Fri, 11 May 2007 17:47:36 -0400

Miika Komu wrote:
> application developer would have to fetch them using a separate
> function call. But maybe this is a weak justification... Second, the
> socket address structure is constrained to 255 bytes. It will fit
> "only" 1 HIT and 15 addresses. Is this enough for e.g. routers?
perhaps strangely, the latter justification makes more sense to me.  no,
15 addresses is not enough.  but it's not acceptable to have the IP
addresses passed implicitly from the resolver to the socket.  offhand,
I'd say that a good compromise would be to allow some reasonable number
of addresses to be specified using sockaddr_hip and to allow more peer
addresses to be added using a setsockopt() call.

---

From: Chris Newman <[email-masked]>
Date: Fri, 11 May 2007 16:46:25 -0700

> library and OS developers?

The IETF's primary focus is to standardize protocols.  But standard protocols 
are of little value if they aren't deployed.  There are various ways to assist 
deployment of protocols and documented APIs are one way.  The IETF has a long 
tradition of publishing APIs, mostly as informational but occasionally on the 
standards track.  There are IETF published APIs of dubious quality that have 
still significantly helped deploy the underlying protocol (I'd point to the 
LDAP API as an example in the applications space).

> for defining such an API and it has already been done successfully for

The primary design goal for an IETF API should be to ease deployment of IETF 
standards-track protocols.  If the APIs designed to ease deployment of HIP also 
ease deployment of IPv6 (which is clearly problematic), that would be a good 
thing.

The key principles from this discussion are:
* Don't bother the busy/lazy/dumb programmers with details they don't need
  or want to know (my point)
* Don't hide any details from programmers who do care (Keith's point)

Data hiding is often good, data losing is always bad.  Be careful to avoid the 
latter when designing those abstractions.

                - Chris

---

From: Chris Newman <[email-masked]>
Date: Fri, 11 May 2007 16:59:31 -0700

> strings like "X$0" and "X$1".

Making an IETF-defined API more complex in order to accommodate non-IETF 
technology seems to go against the primary purpose of an IETF-defined API (to 
ease deployment of IETF protocols).

> scaffolding - or threading - it *can't*.

The sockets API, on the other hand, provides a convenient socket option and 
socket fd/handle suitable for asynchronous use.  Even though the only universal 
API to wait for async socket activity has a terrible design, the simple concept 
of an fd/handle for a socket has allowed operating systems to independently 
develop different asynchronous scaffolding (e.g., poll, /dev/poll, 
port_associate, kqueue, CFNetwork, etc).  So it's possible to design an 
asynchronous-friendly API (like sockets) without limiting the scaffolding and 
with minimal impact on synchronous users.

                - Chris

---

From: Chris Newman <[email-masked]>
Date: Fri, 11 May 2007 18:26:05 -0700

Very simple APIs that solve the 90-95% case are extremely helpful.  Just 
because we also need APIs for the 5-10% case doesn't mean everyone should be 
forced to use the more complex APIs all the time.

One of the reasons HTTP is used (abused) so much is because the deployed APIs 
are very simple, indeed much simpler than sockets.  I've met programmers who 
will gladly toss stuff over HTTP but consider TCP far too complex to consider 
using.  This is very destructive to the actual complexity and security of the 
system.  But that simply doesn't matter to the vast majority of programmers 
when it saves days/weeks of programming time to use the higher level API.

It's also true that many of the deployed HTTP APIs limit control over HTTP 
headers and methods in such a way that it's impossible to use those APIs and 
follow all the advice in BCP 56.  We've seen similar problems with DNS RR 
labels and DNS APIs.

So API designs need to pay attention to both problems and good APIs often have 
both "simple" and "powerful" entry points.  For example, sockets has read/write 
and recvmsg/sendmsg.  As a programmer, I'd really hate to be forced to use the 
latter for all network I/O.

This is an area where good protocol design and good API design differs.  The 
primary goal of good protocol design is interoperability so infrequently used 
features are bad.  The primary goals of (IETF) API design are ease-of-use to 
aid deployment and transparency to avoid data losing -- those requirements 
often force a good design to have infrequently used features.

                - Chris

---

From: Miika Komu <[email-masked]>
Date: Sat, 12 May 2007 19:35:16 +0300 (EEST)

Hi Keith,

> addresses passed implicitly from the resolver to the socket.

Actually, the addresses passed from the resolver would be system level 
"hints" rather than bound to a specific socket because getaddrinfo 
resolver does not know anything about the sockets. What is the exact
reason why you see this as an bad idea?

> offhand, I'd say that a good compromise would be to allow some 
> reasonable number of addresses to be specified using sockaddr_hip and to 
> allow more peer addresses to be added using a setsockopt() call.

I don't see how this would work with the resolver? I guess the only way 
would be to output several HITs redundantly, but with different IP 
addresses. Would this work for you?

I thought about size limitations in more detail. A naive version of 
sockaddr_hip structure and its fields could look as follows based on the 
discussion:

struct sockaddr_hip {
    uint8_t             sinh_len;       /* 1 byte    */
    sa_family_t         sinh_family;    /* 1 byte    */
    in_port_t           sinh_port;      /* 2 bytes   */
    struct in6_addr     sinh_hit;       /* 16 bytes  */
    struct sockaddr_in6 sinh_loc[2];    /* 2 * 112 bytes */
} /* total: 244 bytes (note: maximum size 255 bytes) */

Here I just put two IPv6 addresses inside the structure and assume that we 
use IPv4 address in IPv4-in-IPv6 format. I know that we could insert more 
than two in_addr structures, but it is more complicated to handle. Also, I 
think it is important to have the flowlabels etc for IPv6 addresses, so we 
don't use in6_addr for locators. The port is defined twice; we could use 
the locator port to set the ESP-IN-UDP port number.

The HIT takes 16 bytes. For future extensions purposes, I would actually 
suggest to take the "back-up" locator away and reuse its space with 
16 bytes of reserved space just after the HIT. This way, we could have 
future expansion space for 256 bit HITs? And the single locator would fit 
nicely to the resolver scheme described above.

What about datagram oriented communications? What should happen when the 
HIT and socket remain the same, but locator changes between two sendto() 
calls? I guess it could be used for enforcing an handover.

There also some other protocols around with their own socket address 
structures (un, ipx, atmpvc, ax25, irda, rose, tipc, ash, ec). Perhaps it 
would be more wiser to fix IPv6 format at the API layer and define the 
sinh_loc just as an generic sockaddr.

Does this make sense? I guess this is getting quite specific already, so 
it may be a better idea to move the discussion to HIP mailing lists?

---

From: der Mouse <[email-masked]>
Date: Sat, 12 May 2007 16:21:24 -0400 (EDT)

> great - but it's not the general case.

My "app"?  My app*s*.  I've converted probably at least a dozen
programs to getaddrinfo(), and so far the only one that has had to pry
off the AF-independence hood is a netcat variant which has specific
command-line options to control use of IPv4 and/or IPv6 - and even that
one is ready to handle address families other than v4 and v6 if you
don't use those options.

I can only infer that you and I work on rather different sorts of
networking code. :-)

> for instance, SMTP over DECnet (which does exist, or at least did
> exist) imposed a maximum line length of 512 bytes.

I'd argue that's not SMTP, but a different protocol confusingly similar
to SMTP.  SMTP is relatively well-defined and is rather specifically
*not* tied to TCP:

   SMTP is independent of the particular transmission subsystem and
   requires only a reliable ordered data stream channel.  While this
   document specifically discusses transport over TCP, other transports
   are possible.  Appendices to RFC 821 describe some of them.

> again, it's nice that getaddrinfo() gives you a way to pretend that
> IPv4 and IPv6 are interchangeable for the benefit of the apps that
> can use that feature, but it's not as if all apps can or should work
> that way.

Oh, certainly.  But that's also no reason to impose AF-awareness on
apps that *don't* need it, and as far as I have seen getaddrinfo() is
the only C-language alternative that doesn't impose AF-awareness now.
Have I missed something?

>> I find it about evenly balanced whether getaddrinfo() or doing both
>> INET* AFs is messier, more difficult, whatever.

I have never had to care.  Perhaps this just means I've never run into
a suitably misbehaving getaddrinfo()....

> used getservbyname() and which failed when the NIS server went down
> or the /etc/services file got corrupted EVEN THOUGH THE PORT TO BE
> USED WAS A DEFINED CONSTANT IN THE PROTOCOL SPECIFICATION.

As the people running ssh on ports other than 22 - or SMTP on ports
other than 25 - attest (or, more precisely, running a protocol
otherwise just like ssh on a port other than 22, or a protocol
otherwise just like SMTP on a port other than 25), those "defined
constant"s *aren't* constant in practice.

I still maintain that using strings to name ports is right.

>> The notion that "ports" are small integers is a *horribly*
>> IP-centric notion.

Really?  Most of the specs I've read say things like "can run over any
bidirectional flow-controlled octet stream; when used with TCP, uses
port NN by default" and are actually not IP-centric at all.  Perhaps
you and I have just been working with different sorts of protocols.

> part of the problem is, the definition of the function doesn't
> actually say what the function does with respect to DNS because it's
> too vague - probably as a result of trying to take future

True.  But I think that's better than sticking it with dependency on
current technologies and having to replace it entirely when something
new comes out.  That's what happened with gethostbyname() - which
assumes a host will have addresses in at most one address family - and,
while I won't say getaddrinfo() is entirely right, I think its attempt
to future-proof applications *is* right.  (The desire, that is, not
necessarily the way it went about it.)

>> But it can't really be specified to use DNS, since it is not
>> restricted to address families that the DNS supports

I think we'll have to disagree on this.

But I do know that if something arises which is defined to use the DNS,
I - and anyone else building code which needs to be useful in
environments such as isolated networks where DNS is not available -
will simply not use it.  (For general-purpose name->address resolution,
that is.  I've written code using DNS-specific calls, but only for
things such as MX lookup tools where the job is inherently
DNS-dependent.)

> I've seen so much variation between implementations of getaddrinfo
> that I've become convinced that it needs to be replaced for that
> reason alone.

Perhaps.  But I strongly believe that in order to be useful, any
replacement needs to at least support (not necessarily compel)
AF-agnostic code.  I'd prefer to see it support string port names, too,
but that is relatively easy to fix with a wrapper replacement as
necessary.

> But the variation seems to have resulted from two things: the

I see getaddrinfo() as an experiment in generalizing gethostbyname().
You see it as unfixably flawed while I see it as fixably flawed; that's
not that big a deal (though it's annoying to have to rewrite all my
networking code *again* for yet another new API).  I think the
important disagreements are over what lessons the experiment has to
teach us.

/~\ The ASCII				der Mouse
\ / Ribbon Campaign

---

From: der Mouse <[email-masked]>
Date: Sat, 12 May 2007 17:06:25 -0400 (EDT)

> Second, the socket address structure is constrained to 255 bytes.

This limit borders on trivial to raise.

Well, unless you're trying to do this on an OS whose source is closed
to you, which I submit is a bad vehicle for such research for exactly
this kind of reason.

/~\ The ASCII				der Mouse
\ / Ribbon Campaign

---

From: Miika Komu <[email-masked]>
Date: Sun, 13 May 2007 00:23:17 +0300 (EEST)

> to you, which I submit is a bad vehicle for such research for exactly

Why is it "trivial" to raise? I think it will raise all sorts of backwards 
compatibility problems.

---

From: der Mouse <[email-masked]>
Date: Sat, 12 May 2007 17:47:57 -0400 (EDT)

>> Well, unless you're trying to do this on an OS whose source is
>> closed to you, which I submit is a bad vehicle for such research for
>> exactly this kind of reason.
> Why is it "trivial" to raise?

Just change sa_len, sin_len, sin6_len, sun_len, etc, to short instead
of char.  (You may want to rearrange the element order for better
packing, but that's not essential, just helpful.)

> I think it will raise all sorts of backwards compatibility problems.

Only if you expect to recompile only part of the world.  There might be
code lurking that "knows" those fields max out at 255, but I'd say it's
already broken.

When (if) it comes to releasing OSes with the new _len fields, it gets
a little more interesting, but I'd just version the affected calls and
ignore the issue.

/~\ The ASCII				der Mouse
\ / Ribbon Campaign

---

From: Miika Komu <[email-masked]>
Date: Sun, 13 May 2007 20:18:21 +0300 (EEST)

> code lurking that "knows" those fields max out at 255, but I'd say it's

Not all of the applications are open source. This change would break 
binary applications which is not very nice. The change would affect all 
sockets, not just HIP based sockets.

> a little more interesting, but I'd just version the affected calls and

I don't think that storing of 1 vs. N locators justifies this kind of 
a backwards incompatibility change. It is also a huge deployment barrier.

---

From: Keith Moore <[email-masked]>
Date: Mon, 14 May 2007 09:43:03 -0400

> reason why you see this as an bad idea?

there are lots of reasons.  one is that it unnecessarily couples the
resolver routines with the socket routines, and thereby imposes a
dependency that isn't there now and shouldn't be there.  in other words,
you shouldn't be expected to use the system resolver (e.g. maybe you
want to use an asynchronous DNS library).  another reason is that it
requires the kernel and/or library to manage state that's invisible and
inaccessible to the application - and yet there will probably be
situations that will cause the application to fail if the invisible
state isn't managed like the application expects.  for instance,
consider an app that uses HITs for referrals layered on top of a kernel
that keeps HIT-to-IP mappings only for a limited time before discarding
them.  if the app tries to send to a HIT after that time, the kernel
isn't going to have the mapping any longer.
>> reasonable number of addresses to be specified using sockaddr_hip and
>> to allow more peer addresses to be added using a setsockopt() call.
>
> I don't see how this would work with the resolver? I guess the only
> way would be to output several HITs redundantly, but with different IP
I don't think I understand the question.   You're going to need
different routines to look up HITs, and HIT-to-IP mappings anyway.
> sockaddr_hip structure and its fields could look as follows based on
> the discussion:
>
> struct sockaddr_hip {
> Here I just put two IPv6 addresses inside the structure and assume
> that we use IPv4 address in IPv4-in-IPv6 format. I know that we could
> insert more than two in_addr structures, but it is more complicated to
> handle. Also, I think it is important to have the flowlabels etc for
> IPv6 addresses, so we don't use in6_addr for locators. The port is
> defined twice; we could use the locator port to set the ESP-IN-UDP
> port number.
given that the flow label field in the sockaddr_in6 field isn't even
used in the implementations I've seen (my understanding is that it's not
supposed to be copied to the IPv6 packet), this seems like overkill. 
I'd just put a list of in6_addrs in there.

it bugs me a little bit that there's a port field in there, since HIP is
a layer on top of IP, and there might be IP protocols that don't have
ports.  what if someone wants to run SCTP over HIP?
> The HIT takes 16 bytes. For future extensions purposes, I would
> actually suggest to take the "back-up" locator away and reuse its
> space with 16 bytes of reserved space just after the HIT. This way, we
> could have future expansion space for 256 bit HITs? And the single
> locator would fit nicely to the resolver scheme described above.
>
> What about datagram oriented communications? What should happen when
> the HIT and socket remain the same, but locator changes between two
> sendto() calls? I guess it could be used for enforcing an handover.
interesting question.  actually I think that a HIP association should be
able to exist between two hosts independently of any transport-level
connection, and it might be appropriate to have calls to setup and
discard such associations independently of any connection setup.  that
would yield two cases for datagram communications: in one case the HIP
association would exist and the HIT-to-IP mappings would have been
maintained to keep them current.  in that case the sendto() would just
work, since the sending host would already know how to route to that
HIT. in the other case either there would be no association or no usable
HIT-to-IP mappings (say there had been a network outage and all of the
mappings had expired).   in that case the sendto() would fail with
something like "no route to host" and it would be up to the application
to supply new mappings to the kernel.
> structures (un, ipx, atmpvc, ax25, irda, rose, tipc, ash, ec). Perhaps
> it would be more wiser to fix IPv6 format at the API layer and define
> the sinh_loc just as an generic sockaddr.
>
> Does this make sense? I guess this is getting quite specific already,
> so it may be a better idea to move the discussion to HIP mailing lists?
somehow I think it would be better if the API details were hashed out
here, where they can get wider exposure within the apps area.

Keith

---

From: der Mouse <[email-masked]>
Date: Mon, 14 May 2007 10:18:10 -0400 (EDT)

>>> I think [raising the sa_len limit] will raise all sorts of
>>> backwards compatibility problems.
>> Only if you expect to recompile only part of the world.
> Not all of the applications are open source.

So, version the calls - this is the ABI compatability issue, and it
applies to binary-only apps just as much as to old-binary compat.

>> When (if) it comes to releasing OSes with the new _len fields, it
>> gets a little more interesting, but I'd just version the affected
>> calls and ignore the issue.
> a backwards incompatibility change.

I don't see it as any worse than the incompatibility of switching that
field from short to char in the first place.

But perhaps that's just me.

/~\ The ASCII				der Mouse
\ / Ribbon Campaign

---

From: Keith Moore <[email-masked]>
Date: Mon, 14 May 2007 10:22:28 -0400

have to agree - simply making the length field bigger would break
compatibility for binary object files.

however, you might probably move the location of the length field, leave
sa_family where it is, put a "must be zero" field in its place, and have
the kernel code distinguish between old and new sockaddr structures by
looking at sa_family.

Keith
> binary applications which is not very nice. The change would affect
> all sockets, not just HIP based sockets.
>

---

From: Miika Komu <[email-masked]>
Date: Mon, 14 May 2007 17:56:46 +0300 (EEST)

> isn't going to have the mapping any longer.

Ok. FYI, there is a draft about HIT lookup using DHT:

http://www.ietf.org/internet-drafts/draft-ahrenholz-hiprg-dht-01.txt

> different routines to look up HITs, and HIT-to-IP mappings anyway.

It gets sort of complicated to do two separate lookups in separate 
function calls. In addition, the HIT lookup may or may not work because 
HITs are flat identifiers. I'd just a use single function call.

Let's take an example of looking up "foo.bar" which maps to HIT1, HIT2, 
HIT3 and IP1, IP2, IP3, IP4, IP5, IP6.

We can return the following from the resolver:

item1: HIT1+IP1,IP2,IP3,IP4,IP5,IP6
item2: HIT2+IP1,IP2,IP3,IP4,IP5,IP6
item3: HIT3+IP1,IP2,IP3,IP4,IP5,IP6

But then we have to modify the size of the family in sockaddr. 
Alternatively, we can return:

item1: HIT1+IP1
item2: HIT1+IP2
item3: HIT1+IP3
item4: HIT1+IP4
item5: HIT1+IP5
item6: HIT1+IP6
item7: HIT2+IP1
item8: HIT2+IP2
...

and now the family size does not change The drawback here is that this may 
reduce the latency to connect when some of the locators are broken 
especially when the application does not parallerize multiple connect() 
calls.

I'd choose the second approach based on the earlier discussion that the 
intelligence should reside on the application or socket wrapper library. 
So we can assume that the entity operating on top of sockets API can do 
the right thing.

The first approach is also inefficient. Even though longer socket address 
structures can be made to work, they require more sockaddr copying between 
userspace and kernelspace especially with datagram oriented sockets.

Comments?

> I'd just put a list of in6_addrs in there.

We have a tradeoff here between future compatibility (un, ipx, atmpvc, 
ax25, irda, rose, tipc, ash, ec), which requires sockaddr, and saving 
space for multiple IP addresses (in6addr).

> ports.  what if someone wants to run SCTP over HIP?

This would call for the sockaddr structure and encapsulating the port 
number inside that when needed?

> to supply new mappings to the kernel.

Yes.

Ok.

---

From: der Mouse <[email-masked]>
Date: Mon, 14 May 2007 10:52:43 -0400 (EDT)

> compatibility for binary object files.

Yeah; as I mentioned, you just need to version the calls.

> however, you might probably move the location of the length field,
> leave sa_family where it is, put a "must be zero" field in its place,

I really dislike that idea.  sockaddr_in effectively has a "must be
zero" field now, under at least some OSes, and I think it is a horrible
botch.  Doing this would also render existing working source broken by
fiat (because it doesn't zero this new field), which strikes me as a
very bad idea.

Unless you mean, do this only for AF_HIT or whatever the new AF_ is, in
which case only the MBZ comment applies - which I think is *also* a bad
idea, because it means that sockaddr_hit cannot be punned with sockaddr
or soackaddr_storage the way all other sockaddr_*s can be.

/~\ The ASCII				der Mouse
\ / Ribbon Campaign

---

From: Tony Finch <[email-masked]>
Date: Mon, 14 May 2007 15:49:59 +0100

> the kernel code distinguish between old and new sockaddr structures by

That has already been done for the 4.3BSD -> 4.4BSD sockets API changes.
The sockaddr was originally designed to have an external length (as you
can see in connect() and other calls) but 4.4BSD messed this up by moving
to an embedded length field.

Tony.
-- 
f.a.n.finch  <[email-masked]>  http://dotat.at/
TYNE DOGGER: CYCLONIC 4 OR 5, OCCASIONALLY 6, BECOMING VARIABLE 3. MODERATE OR
ROUGH. RAIN OR SHOWERS. MODERATE OR GOOD.

---

From: der Mouse <[email-masked]>
Date: Mon, 14 May 2007 11:40:49 -0400 (EDT)

> I am curious.  Even though this is irrelevant for the discussion, can
> be more specific on what is broken with getaddrinfo?

The major annoyance it has for me is the requirement that, to quote the
manpage for the version I use, "[i]n this hints structure all members
other than ai_flags, ai_family, ai_socktype, and ai_protocol must be
zero or a NULL pointer".  This requires the app to either have a static
struct addrinfo around or to know the complete list of members of the
struct - and it's completely unnecessary as far as I can see.  (It
makes sense to have some kind of extensibility hook, but that could be
done with a bit in ai_flags, or at least listing the fields that have
to be zeroed rather than requiring it of all except a list.)

Not a big problem, true.  But annoying.  (Apparently the getaddrinfo()
I've got used to doesn't suffer from most of the brokennesses outlined
in this thread.  If I had to deal with them I'd have a lot more to say
here, I'm sure.)

/~\ The ASCII				der Mouse
\ / Ribbon Campaign

---

From: Tony Finch <[email-masked]>
Date: Mon, 14 May 2007 17:28:23 +0100

On Mon, 14 May 2007, der Mouse wrote:
> struct - and it's completely unnecessary as far as I can see.

You should be able to just memset() it to 0. (I believe POSIX gives you
more guarantees than C in this respect.)

Tony.
-- 
f.a.n.finch  <[email-masked]>  http://dotat.at/
FORTIES: NORTHWESTERLY 5 TO 7, BECOMING CYCLONIC FOR A TIME, DECREASING 4
LATER. MODERATE OCCASIONALLY ROUGH AT FIRST. SHOWERS. MODERATE OR GOOD.

---

From: der Mouse <[email-masked]>
Date: Wed, 16 May 2007 13:21:23 -0400 (EDT)

>> The major annoyance [getaddrinfo] has for me is the requirement
>> that, to quote the manpage for the version I use, "[i]n this hints
>> structure all members other than ai_flags, ai_family, ai_socktype,
>> and ai_protocol must be zero or a NULL pointer".
> You should be able to just memset() it to 0.  (I believe POSIX gives
> you more guarantees than C in this respect.)

POSIX requires nil pointers to be all-bits-zero?  That's..bizarre.
Must be rather crippling for anyone trying to work with oddball
architectures.

I'd also recommend against depending on it when designing interfaces;
these interfaces get used in not-quite-POSIX and sometimes even
not-even-close-to-POSIX systems, and I think it would be good if they
didn't depend on POSIX features unnecessarily - and I see this as a
totally unnecessary dependency.

/~\ The ASCII				der Mouse
\ / Ribbon Campaign