Hi Ran, Tony and Steve,
One of the key features claimed for ILNP is that it can work properly
with unmodified IPv6 applications. By this I mean that it can
provide host-multihoming, site-multihoming and mobility, between two
hosts with ILNP-equipped stacks, between all applications.
This has already been stated:
RRG Report Summary:
ILNP can be implemented such that existing applications (e.g.
applications using the BSD Sockets API) do NOT need any changes
or modifications to use ILNP.
draft-rja-ilnp-intro-05:
9.1 BSD Sockets APIs
The existing BSD Sockets API can continue to be used with
ILNP underneath the API. That API can be implemented in a
manner that hides the underlying protocol changes from the
applications.
I am trying to understand how the stack would achieve this. Here is
my attempt to figure it out, with various questions I hope you can
answer.
To simplify the discussion, I assume:
ILNPv6 only.
BSD sockets interface only with the application using stream
and datagram calls (TCP and 2-way UDP) and performing all DNS
queries via getaddrinfo(). (There would be quite a few apps which
use raw sockets, do their own DNS lookups etc. I doubt these
could work with ILNP.)
The application starts with FQDNs as the mechanism to specify the
one or more hosts it will communicate with. (I think quite a
few applications have other mechanisms for determining the IP
addresses of hosts they communicate with. As far as I know,
these won't work with ILNP - these involve IP-address
"referrals".)
All Identifiers are globally unique.
I assume a single Identifier is returned from the lookup of the
FQDNs. (ILNP can implement the equivalent of round-robin DNS
by having the DNS return multiple Identifiers, but they must
all share the same Locators - that is, these hosts must all have
the same sets of ISPs, so they are accessible via the same set of
/64 prefixes.)
I am not trying to check the system for robustness against attacks
- just trying to imagine how it would work in the simplest
realistic case I can imagine.
The example (to be continued in later messages) concerns 3 ILNP hosts
A, B and C and a fourth, ordinary, IPv6 host D, whose IP address I
will depict as "KKKK-LLLL".
I am using four characters to represent 64 bits, so "PPPP-QQQQ" means
the upper 64 bits (Locator) are symbolized by "PPPP" and the lower 64
bits (Identifier) by "QQQQ". "0000-QQQQ" denotes the upper 64 bits
being zero.
Host A B C D
FQDN for A.FOO.NET B.BAR.NET C.BAZ.NET D.ZOT.NET
this host
IP address
from the point
of view of
ordinary IPv6
applications EEEE-AAAA GGGG-BBBB IIII-CCCC KKKK-LLLL
Identifier AAAA BBBB CCCC
Locators EEEE GGGG IIII
FFFF HHHH JJJJ
A, B and C are multihomed via two ISPs each. From the point of view
of the routing system (globally, and down to their local network
level) each of A, B and C has two IP addresses. For instance, A has
both:
EEEE-AAAA and FFFF-AAAA
I assume that the ILNP-modified stack either presents to the IPv6
apps in A the impression that A has both addresses, or only makes one
available. (How this would be chosen, and how it would work, I have
not tried to figure out.) I will assume each ILNP stack only
presents the first of its host's two IP addresses to ordinary IPv6
applications as the host's address.
If D initiates a session with any of the applications in A, B or C -
perhaps via the one IP addresses which the ILNP stack supports for
ordinary IPv6 communications - the ILNP stack in A, B or C needs to
behave exactly like an ordinary IPv6 stack, so the applications at
each host can communicate as usual.
In principle this can be decided by the stack seeing the initial
packet from D arrive without an extension header with an ILNP nonce.
(BTW, an ILNP host only sends a nonce on the "Initial" packet.
This is easy to figure out with a TCP session, but what about
an application on A which starts sending UDP packets to a novel
destination host, say host C? The ILNP stack in A might have
some algorithm to decide that the first outgoing UDP packet to
C is "initial" - and so would add the nonce. I foresee
problems with Path MTU Discovery - how could it do this and
somehow tell the application a realistic maximum size for the
UDP payload, when the first packet has this extra nonce
header?
But let's say that first packet is lost. The application
retries - and the ILNP stack in A has no reason to consider
this second packet to C as being "initial" - so it doesn't add
a nonce.
The first packet to arrive at C is the second packet - without
a nonce. So the ILNP stack in C will decide that A is not an
ILNP equipped host, and will treat the packet exactly like an
ordinary IPv6 stack. There will be no way after that for C to
discover that A was really an ILNP host.
It seems this reliance on sending a nonce only on the "initial"
packet is rather fragile.)
Now I will try to imagine how B runs a server on TCP port 80 and A
has a web client on TCP 2000, which sends an initial packet (TCP SYN)
to B's port 80.
The web client application in A initiates this session by starting
with "B.BAR.NET". It uses getaddrinfo() to do a DNS lookup of this
FQDN and the ILNP-stack processes this and sends a request packet to
the DNS. The reply arrives at A's ILNP-equipped stack. (I will
assume the query requested all records and that there is no LP
record, so the full results come back in the reply.) The reply includes:
ID: BBBB Preference 1
L64: GGGG Preference 1
L64: HHHH Preference 2
The ILNP stack keeps note of these items. I won't try to imagine the
exact details, though the I-Ds give details of the state the stack
keeps for each session.
What IP address does the ILNP-stack return to the web client
application?
GGGG-BBBB
or 0000-BBBB?
There will be other things in the returned structure addrinfo, but
the only one which matters to us now is the binary address contained
in the sockaddr structure within addrinfo. I assume that only one
addrinfo will be returned, and not two, such as with GGGG-BBBB and
HHHH-BBBB.
The ILNP I-Ds do not seem to specify how the stack returns the
results of DNS queries to applications. The three items which seem
most relevant are:
draft-rja-ilnp-icmp-02
5. Backwards Compatibility
For all sessions operating in Identifier/Locator Split
mode, inside each node the high-order 64-bits ("Locator")
are always set to zero before the packet is sent upwards to
the transport protocol.
draft-rja-ilnp-intro-05
3. TRANSPORT PROTOCOLS
With this proposal, transport protocols include only the
Identifier in their pseudo-header calculations, but do not
include the Locator in their pseudo-header calculations.
To minimise the changes required within transport protocol
implementations, when this proposal is in use for a
communications session, the Locator fields are zeroed for
the purpose of transport-layer pseudo-header calculations.
9.1 BSD Sockets APIs
The existing BSD Sockets API can continue to be used with
ILNP underneath the API. That API can be implemented in a
manner that hides the underlying protocol changes from the
applications. For example, the combination of a Locator
and an Identifier can be used with the API in the place
of an IPv6 address.
The first and second items above imply that the application would be
given 0000-BBBB. The third implies that it would be given GGGG-BBBB.
How would the ILNP stack behave?
I will continue on the assumption that the ILNP stack gives the
application 0000-BBBB - because this makes more sense to me than
giving it GGGG-BBBB and then letting it open a socket to GGGG-BBBB,
when the upper bits are to be zeroed, for the purpose of
pseudo-header calculations, and then replaced (when constructing the
destination address) with the ILNP stack's choice of GGGG or HHHH.
So the web client application gets the IP address 0000-BBBB and opens
a socket with this address to be the destination address of the
resulting TCP packets. It then calls connect() and the ILNP stack
sends a TCP SYN packet to, I assume GGGG-BBBB. The ILNP stack in A
determines this is an "initial packet" and so adds a destination
option with a unique ILNP nonce. I assume that the source address of
the packet leaving A is EEEE-AAAA, but it just as easily could be
FFFF-AAAA. I will assume it is sent from TCP port 3333.
Before this, what must have happened in host B for the web server
application to have opened what it thinks is a socket on its own IP
address? I assume the ILNP stack has told the application the host's
IP address is GGGG-BBBB.
The server application on B must have (in order for the ILNP stack to
retain backwards compatibility with IPv6) opened what for all intents
and purposes is an ordinary TCP Listen socket on its IP address
GGGG-BBBB, port 80.
If a web client in D sends an ordinary IPv6 packet to TCP port 80 at
B's IP address HHHH.BBBB, then I assume the ILNP stack will ignore
it, because the server application hasn't opened a socket on this
address. If the web client on D sends such a packet to GGGG.BBBB,
then the ILNP stack in B must present the packet as usual: from
KKKK-LLLL, and whatever port number there - so the server application
can respond normally.
For ILNP to work, the ILNP stack in B must be ready to accept packets
with an ILNP nonce, addressed to TCP port 80 on either of its
addresses GGGG-BBBB or HHHH-BBBB, and transform either event into an
identical set of information for the application.
It is clear from the first two quoted items above that the stack does
this by zeroing the upper 64 bits of the source address. So the when
A's packet arrives at GGGG-BBBB on B, the ILNP stack there tells the
TCP layer, and through it the server application, that the packet has
arrived from:
0000-AAAA
Now, for simplicity, I am going to assume something which is not
realistic for ILNP: that the application and stack in B will simply
reply to host A, without in any way checking that the host with
Identifier AAAA really has the Locator GGGG. (That is a whole other
discussion.)
The server application in B, or perhaps it is just the TCP layer in
B, then responds with a SYN-ACK packet to what it sees as 0000-AAAA -
and the ILNP stack alters this address to add the only Locator it
knows for AAAA (actually, it doesn't know it really is AAAA's
Locator) so far:
EEEE-AAAA
The ILNP stack somehow (I guess from its integration with the TCP
layer) recognises this as an "initial packet" and so it adds an ILNP
nonce. Then the packet goes back to A, and the ILNP stack there
stores the nonce, zeroes the upper 64 bits of the source address, and
presents it to the TCP layer.
The TCP layer in A sends its second packet - an ACK - to B. This is
internally addressed to 0000-BBBB, but the ILNP stack changes this to
GGGG.BBBB
and sends it, without an ILNP nonce, again from EEEE.AAAA.
The ILNP stack in A could just as easily have decided, for some
reason, that it should send the packet to HHHH.BBBB instead, since
both these addresses are valid combinations of Locators and
Identifier for B. It also could have sent the packet out the other
ISP link, from FFFF.AAAA.
For all four combinations of this, once the ACK packet arrives at B,
B's ILNP stack needs to pass it on to the TCP layer, with the source
address set to 0000.AAAA. Then the TCP layer will regard the session
as open, and the server application will be able to accept higher
level protocol commands, and send back replies - all of which will go
without ILNP nonces.
Ran - do both A's ILNP stack and B's ILNP stack also send ICMP
packets to each other, secured by the nonce the received from the
other, to tell each other their full set of Locators? I understand
each host's ILNP stack does this if its Locator changes. A's ILNP
stack doesn't need this, since it just looked up B's Identifier and
Locators from B's FQDN. However, B's ILNP stack has no idea what A's
other Locator(s) if any, are. Is the ICMP message meant to be used
at session initiation, like this - or is it only to be used if a host
changes its Locators?
I don't recall from reading all your I-Ds where this is is described.
Unless A's ILNP stack sends such an ICMP message, I think the only
way B's ILNP stack could find out about A's other Locator is
something quite onerous:
1 - B's ILNP stack does a reverse DNS lookup of the IP address
EEEE-AAAA.
2 - Assuming the ISP which provides A with the EEEE /64 address
is running its reverse DNS correctly, then this should return
A's FQDN.
!!! This seems like a tall order - for A's network to
ensure that both its ISP's update their reverse DNSes
for every host in the network. IF A's network is the
only customer using the EEEE /64, then perhaps this
network could run the reverse DNS for this /64, and
likewise for the FFFF /64. But if these ISPs had any
other customers on these /64s, this wouldn't be possible
and it would be necessary for the ISP's own reverse
DNS to be securely updated by each such customer,
to install a unique FQDN for each ILNP host. This is
in addition to each network separately ensuring that
its ordinary DNS has an entry for each of its hosts,
with the ILNP records as required.
3 - B's ILNP stack does a DNS lookup of A's FQDN and so reliably
obtains A's Identifier and two Locators.
That's enough questions for now.
To be continued.
- Robin
_______________________________________________
rrg mailing list
[email protected]
http://www.irtf.org/mailman/listinfo/rrg