The RPC2 IPv6 code is copyright (c) 2002, Nokia.  The author is Rod
Van Meter (Rod.VanMeter@Nokia.com or rdv@alumni.caltech.edu).  As part
of the RPC2 suite, this code is licensed under the LGPL.

This code is a rewrite of the key networking code, following the
advice of Metz [1], to be protocol independent.  It replaces the IPv4
code with code intended to support both IPv4 and IPv6.  The code uses
the more modern getaddrinfo() to replace gethostbyname() [2].

The new code has been tested to work (using stest and ctest) both
within a node (using the loopback address) and between a pair of nodes
with globally routable IPv6 addresses, using DNS names.  Also tested
for IPv4.

This should, in theory, work over Mobile IPv6, which should enhance
its overall usability.  This is not yet tested.

COMPILING AND INSTALLING

To turn on this code, compile with

#define CODA_IPV6

To do this, at the moment, I run ./configure, then put the following
at the bottom of the generated config.h:

/* XXX hand-hacked by rdv */
#define CODA_IPV6


TODO

This is, so far, VERY incomplete code, and reflects my still-evolving
understanding of the best way to write protocol-independent code.
Some of these are marked with XXX in the source.

(- comments from Jan)

* One goal is to eliminate RPC2_PortIdent and rpc2_LocalPort and keep
  it all in one structure, RPC2_HostIdent.  This is only partially
  done.
- What RPC2_PortIdent? ;) I removed pretty much all references and now
  only sftp and 2 seemingly unused tracebuffer entries still use it.

* There are probably ways to reduce further the dependence on
  sockaddr_in and sockaddr_in6.  Some of the existing use is probably
  not type safe, too.
- Removed most places we used them. We only use it in 3 places now, reporting
  bound port, when a packet is received and when we convert addrinfo to a
  "hostip:port" string.

* This is only in the RPC2 code.  To be useful, it needs to be
  incorporated into the full Coda code, including things like the
  configuration files.
- Current interface only requires userspace to handle returned
  HostIdent's that contain an addrinfo type, which is now the only one
  we return as everything in rpc2 uses addrinfo.

* I'm far from certain, at this point, that I'm not leaking memory
  with the malloc()s I'm doing for addrinfo.
- Using my own 'rpc2_addrinfo' so that I actually know the allocation
  policy and can handle deep copy operations and freeing structures.

* I'm equally uncertain that what I have is thread safe, to the extent
  that the code can handle concurrent requests.
- It seems to be. Ofcourse it is LWP-thread safe, which is far simpler
  than pthread safe.

* Multi-valued returns from getaddrinfo, which are the norm, are not
  yet handled properly.  The code should look through the list to find
  the best one for its purposes, perhaps by trying them all.  This is
  especially important given that not all clients and servers will
  support v6 right away.
- NewBinding now tries all addresses until it gets a hit. On the
  listener side we probably should bind to all returned addresses, but
  then we get multiple sockets and have to figure out which socket to
  use for replies, or get yet another unbound socket for those.

* There are too many places with #ifdef CODA_IPV6...#else...This is
  fragile code.
- One place left, and that is where we tie into the fail filter.

* I'm sure there are error conditions I'm not catching right yet.
- I probably got them all.

* So far, this is only tested on Linux (Red Hat 8.0 with the stock
  2.4.18-14 kernel).  I'll test it on FreeBSD 4.x and other Linux
  kernels at some point, but someone else will have to test the
  broader range of systems.  The APIs should be the same, but
  differences in behavior (e.g., ordering of addresses returned) may
  affect it.
* As mentioned above, not yet tested over Mobile IP.
* Testing so far consists of running stest and a single ctest.  There
  are probably bugs lurking that aren't exercised with this simple
  setup.
* Not yet tested with scoped (site or link local) addresses, other
  than the loopback address.  This probably needs code (the advanced
  sockets API [3]).
* Not yet tested on a system that supports v6 but doesn't have the
  module loaded or IPv6 otherwise enabled.  I'll bet
    if (error = getaddrinfo("::1", NULL, &req, &ai))
      if (error = getaddrinfo("localhost", NULL, &req, &ai))
  will do it.
- According to the manpage the following should do the trick,
  hint.ai_flags = AI_PASSIVE;
  error = getaddrinfo(NULL, service, &hint, &ai);

References

[1] Metz, C., "Protocol Independence Using the Sockets API", FREENIX
2000, June 2000.
http://www.usenix.org/publications/library/proceedings/usenix2000/freenix/metzprotocol.html

[2] R. Gilligan, S. Thomson, J. Bound, W. Stevens,  "Basic Socket
Interface Extensions for IPv6", RFC2553, March 1999.

[3] W. Stevens, M. Thomas, "Advanced Sockets API for IPv6",  RFC 2292,
February 1998.
