1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
|
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.
|