[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

huitema-v6ops-teredo-01 comments



Hi,

I did a rather thorough reading of Teredo-01 on the plane.  Comments 
below...

substantial
-----------

1) sect 5.2.1, qualification procedure seems to yield either cone NAT,
restricted cone NAT or symmetric NAT.  What about port-restricted cone
NATs?  Are these implicitly covered in some terminology here?  They
don't seem to be explicitly mentioned anywhere!

2) security considerations should discuss that MD5 is not anymore 
considered "secure" due to better collision-resistance of SHA1.  
However, in this specific case, I don't think this is a huge problem.

3) I think this document seriously needs an "overview" section, around 
section 4, which could be e.g. 2-4 pages, trying to summarize the 
whole operation while leaving out the details with figures, etc. -- 
whatever appropriate.  The spec is rather compact and requires careful 
reading to understand its implications.  Having such a section (as 
there was before, but it was removed, I think) would be very useful 
for those who want to get a good overview of how the mechanism works.

4) what's the implementation status?  to what degree do the 
implementation(s) reflect the current spec?  I have a few thoughts for 
improvements if certain parts of the spec would not be implemented yet 
(e.g., the authentication encapsulation), but if they are, making such 
changes might not be feasible.

5) an interesting deployment model could be deploying a
Teredo-cognizant tunnel broker at the teredo anycast address,
basically "hijacking" all the teredo users as your tunnel broker
customers -- requiring no tunnel broker implementations at the client
side.  This would be a rather interesting way to leverage the existing
implementations to provide tunnel broker service :-).

6) this doc probably needs a bit more applicability etc. work but 
that's something that can be inserted a bit later on as well.

semi-editorial/substatial
-------------------------

Abstract
                                                                                                                  
   We propose here a service that enables nodes located behind one or
   several IPv4 NATs to obtain IPv6 connectivity by tunneling packets
   over UDP; we call this the Teredo service. Running the service
   requires the help of "Teredo servers" and "Teredo relays"; the
   Teredo servers are stateless, and only have to manage a small
   fraction of the traffic between Teredo clients; the Teredo relays
   act as IPv6 routers between the Teredo service and the "native" IPv6
   Internet.

==> the last sentence is not accurate when you take also the "6to4
universe" into account -- needs rewording somehow?

   A possible way to solve the problem is to rely on a set of "tunnel
   brokers." There are however limits to any solution that is based on
   such brokers: the quality of service is not very good, since the
   traffic follows a "dog leg" route from the source to the broker and
   then the destination; the broker has to provide sufficient
   transmission capacity to relay all packets and thus suffers a high
   cost. For these two reasons, we tend to prefer solutions that allow
   for "automatic tunneling", i.e. let the packets follow a direct path
   to the destination.

==> I'd reword this to a bit softer, because tunnel brokers are 
actually useful in some contexts: 
==> s/is not very good/may be limited/
==> s/we tend to prefer/it may be desirable to have/

2.8     Teredo service port
                                                                                                                  
   The port through which the Teredo client sends Teredo packets. This
   port is attached to one of the client's IPv4 interfaces. The IPv4
   address may or may not be globally routable, as the client may be
   located behind one or several NAT.

==> ports are not attached to interfaces.  They may be attached to 
addresses only.  So, maybe rename "Teredo service port" to "Teredo 
service address/port" or whatever, and reword the text a bit?

   Experience shows that the implementers of NAT devices can adopt
   widely different treatments of UDP mappings:

==> if this has been analyzed at more length elsewhere, I'd refer to 
that work for additional information.  Later in the document, RFC3489 
is cited as one source, at least.

   3) Instead of keeping just a list of authorized hosts, some NAT
   implementations keep a list of authorized host and port pairs. UDP
   packets coming from remote addresses are rejected if the internal
   host has not yet sent traffic to the outside host and port pair. The
   NATs are often called "port-restricted cone NATs"

==> I've always had problems figuring out what this means.  I suggest 
adding a new second-to-last sentence:

  That is, as long as the internal host has communicated with a (host, 
  port) pair, the created NAT mapping (to some other host or port) can 
  be used to inject incoming packets to the internal host.

3.2.1   When to use Teredo?
                                                                                                                  
   Teredo is designed to robustly enable IPv6 traffic through NATs, and
   the price of robustness is a reasonable amount of overhead, due to
   UDP encapsulation and transmission of bubbles. Nodes that want to
   connect to the IPv6 Internet SHOULD only use the Teredo service as a
   "last resort" option: they SHOULD prefer using direct IPv6
   connectivity if it is locally available or if it is provided by a
   6to4 router co-located with the local NAT, and they SHOULD prefer
   using the less onerous "6to4" encapsulation if they can use a global
   IPv4 address.

==> this doesn't yet describe tunnel service (details TBD at the 
moment) at all -- it is also a preferable choice.

4       Teredo Addresses

==> I'd consider separating this to two subsection, global and 
link-local addresses -- as these seem to have slightly different 
characteristics.

   -    The bits indicated with "z" must be set to zero.

==> s/set to zero/sent as zero and ignored on receipt/ ?

   The Teredo relay advertises reachability of the Teredo service
   prefix over IPv6. It forwards Teredo IPv6 packets to the appropriate
   IPv4 address and UDP port.

==> local relays don't do the first.  This has been ignored in a few
other places in the document as well.

   The following 16 bits contain the obfuscated value of the port
   number from which the packet was received, in network byte order.
   The next 32 bits contain the obfuscated IPv4 address from which the
   packet was received, in network byte order. In this format, both the
   original "IPv4 address" and "UDP port" of the client are obfuscated.
   Each bit in the address and port number is reversed; this can be
   done by an exclusive OR of the 16-bit port number with the
   hexadecimal value 0xFFFF, and an exclusive OR of the 32-bit address
   with the hexadecimal value 0xFFFFFFFF.
                                                                                                                 
   For example, if the original UDP port number was 337 (hexadecimal
   0151) and original IPv4 address was 1.2.3.4 (hexadecimal: 01020304),
   the origin indication would contain the value "0000FEAEFEFDFCFB".

==> this obfuscation code has been described in two places -- maybe it 
would make sense to put it in a subsection or something, so it could 
be referred to more easily when it's used later on in the draft?

   The third octet indicates the length of
   the client identifier;  the fourth octet indicates the length of
   the authentication value.

==> is zero client ID OK as well?  The same about authentication 
value? (these could be useful if you'd only want "return routability" 
like anonymous testing, where you'd only want to use nonces.

==> these octets give the length in the units of bytes, correct? (make 
explicit)

 In
   accordance with [RFC2461], the default time-out value is set to T=4
   seconds, and the maximum number of repetitions is set to N=3.

==> this seems quite long, and I don't see how RFC2461 relates here.  
Maybe e.g. T=2, N=1 would be sufficient?

   option. This prefix should be a valid Teredo IPv6 server prefix: the
   first 32 bits should contain the global Teredo IPv6 service prefix,
   and the next 32 bits should contain the server's IPv4 address. If
   this is the case, the client learns the Teredo mapped address and
 
==> "global" --> remove that, could be local as well?

   If the client has received an RA with the "Cone" bit set to 1, it is
   behind a cone NAT and is fully qualified. If the RA is received with
   the Cone bit set to 0,  the client does not know whether the local
   NAT is restricted or symmetric. The client selects a secondary IPv4
   server address, and repeats the procedure, the cone bit remaining to
   the value zero.

==> there are multiple places where Cone bit can be set, so maybe 
reword like:

   If the client has received an RA with the "Cone" bit in the 
   advertised prefix set to 1, it is behind a cone NAT and is fully
   qualified. If the RA is received with the Cone bit in the 
   advertised prefix set to 0,  the client does not know whether the 
   local NAT is restricted or symmetric. The client selects a 
   secondary IPv4 server address, and repeats the procedure, the cone 
   bit in the link-local address remaining to the value zero.

....

   indication. The cone bit should be set to the value used to receive
   the RA, i.e. 1 if the client is behind a cone NAT, 0 otherwise. The

==> s/to receive the RA/in the RA/ ?  Or am I confused about cone bit 
in the prefix vs. link-local address?

   When a UDP packet is received over the Teredo service port, the
   Teredo client checks that it is encoded according to the packet
   encoding rules defined in 5.1.1, and that it contains either a valid
   IPv6 packet as specified in [RFC2460],

==> you must spell out what exactly to check, as RFC2460 does not 
specify what is a "valid IPv6 packet".  The same happens a lot later 
in the spec as well.

if an origin indication is
   present, the client should perform the "direct IPv6 connectivity
   test" described in section 5.2.9.

==> should you use more uppercase keywords, e.g., in here, but in 
several other places as well?

 If the values match, the packet
   should be accepted; the date and time of the last reception from the
   peer should be updated.

==> s/should be/is/ ?

                                                                                                  
   2) If there is an entry for the source IPv6 address in the list of
   peers whose status is not trusted, the client checks whether the
   packet is an ICMPv6 echo reply. If this is the case, and if the
   content of the reply matches the "nonce" stored in the peer entry,
   the packet should be accepted;

==> s/content/ICMPv6 data/

any packet queued for this IPv6
   peer should be de-queued and forwarded to the newly learned IPv4
   address and UDP port.

==> add a pointer to 5.2.4 around queuing?

   4) If the source IPv6 address is a Teredo address, and the mapped
   IPv4 address and mapped port in the source address do not match the
   source IPv4 address and source port of the packet, the client checks
   whether the is an existing "local" entry for that IPv6 address. If
   there is such an entry, and if the local IPv4 address and local port
   indicated in that entry match the source IPv4 address and source
   port of the packet, the client updates the "local" entry, whose
   status should be set to "trusted". If the packet is a bubble, it
   should be discarded after this processing; otherwise, the packet
   should be accepted. In all cases, the client must de-queue and
   forward any packet queued for that destination.

==> and what if there is no such entry?  do nothing?

   5) If the IPv4 destination address through which the packet was
   received is the Teredo IPv4 Discovery Address, the source address is
 
==> add a note here stating that this procedure is optional.

   2) If the destination is not a Teredo IPv6 address, the packet is
   queued, and the client performs the "direct IPv6 connectivity test"
   described in section 5.2.8. The packet will be de-queued and

==> s/5.2.8/5.2.9/

5.2.6   Sending Teredo Bubbles

==> this section should also discuss "indirect bubbles" (as introduced 
in 5.2.4) and how they're sent.

   the client MUST create a new list entry for the address,
   setting the last reception date and the last transmission date to 30
   seconds before the current date, and the number of bubbles to zero.

==> umm.. why exactly are you setting the dates to 30 seconds in the 
history??

   The secondary port MUST NOT be used for any other purpose than the
   interval determination procedure. If a spurious packet is received on
   the secondary port, the client SHOULD repeat the maintenance
   procedure on this port and reset the date and time of the last
   interaction on the secondary port.

==> umm,, this would seem to hint at an implementation technique, 
where you'd be continously listening at the secondary port.  I fail to 
see the need for that -- this is only done when you start up Teredo 
(if it's implemented that is).  Rather, just specify that the port is 
closed when the procedure ends?

   A Teredo client who wishes to enable local discovery SHOULD wait for
   discovery bubbles to be received on the Teredo IPv4 Discovery
   Address, and should send local discovery bubbles to the Teredo IPv4
   Discovery Address at random intervals

==> which -- wait _or_ send?  Or both?  Make it more explicit.  Maybe 
just say that one should join the group. 

   - IPv6 source: the Teredo IPv6 address of the sender
                                                                                                  
==> is this the global or link-local address?

5.3     Teredo Server specification
                                                                                                  
==> you should really add text here describing the forwarding of 
ICMPv6 probes, and bubbles between Teredo and non-Teredo nodes.

==> also, you should mention the requirement about the secondary 
address on the server.

   Upon reception of a packet on the Teredo port, the Teredo server
   will first check that the UDP payload contains a valid IPv6 packet;
   if this is not the case, the packet will be silently discarded.
                                                                                                  
   Before processing the packet, the Teredo server MUST check the
   validity of the encapsulated IPv6 source address, the IPv4 source
   address and the UDP source port:
                                                                                                  
   1)   If the UDP content is not a well formed IPv6 packet, the packet
   MUST be silently discarded.

==> isn't the first paragraph unnecessary, compared to 1)?
==> you don't define well-formed?

   2)   If the UDP packet is not a bubble or an ICMPv6 message, it should
   be discarded.

==> should probably add a pointer for the definition of a bubble.
==> should you use upper-case keywords in a place like this?

   4)   If the IPv6 source address is an IPv6 link-local address, the
   IPv6 destination address is the link-local scope all routers
   multicast address (FF02::2), and the packet contains an ICMPv6
   Router Solicitation message, the packet SHOULD be accepted; it
   MUST be discarded if the server requires secure qualification and
   the authentication encapsulation is absent or cannot be verified.

==> SHOULD be accepted?  What's the alternative -- discard them?  
Shouldn't this be a mandatory part? (Same later in 5) and 6)
==> s/cannot be verified/verification fails/ ?

   The Teredo server will then check the IPv6 destination address of
   the encapsulated IPv6 packet.

==> s/./:/
==> maybe the following paragraphs should be similarly separated to 
1), 2) and 3) for clarity?

   If the IPv6 destination address is a valid Teredo IPv6 address, the
   Teredo Server MUST check that the IPv4 address derived from this
   IPv6 address is in the format of a global unicast address

==> a link-local address is also a valid Teredo address, right?  But 
not applicable here?  Maybe needs spelling out which specific address 
type?

   If the destination IPv6 address is a Teredo client whose address is
   serviced by this specific server, the server should insert an origin
   indication in the first bytes of the UDP payload, as specified in
   section 5.1.1.

==> how can the server know which addresses it's supposed to be 
servicing?  Or are you really saying, "if received through the Teredo 
interface.." ?

The IPv6 source address should
   be set to a Teredo link-local server address associated to the local
   interface.

==> how exactly did you form the LL address on the server?  What about 
the C-bit?

 However, Teredo relays do not have to
   perform the qualification procedure.

[...]
   In cases 2 and 3, the Teredo relay should create a peer entry for
   the IPv6 address; the entry status is marked as trusted in case 2
   (cone NAT), not trusted in case 3. In case 3, if the Teredo relay
   happens to be located behind a non-cone NAT, it should also send a
   bubble directly to the mapped IPv4 address and mapped port number of
   the Teredo destination; this will "open the path" for the return
   bubble from the Teredo client.

==> aren't these in conflict?  The relay don't know which NAT it's 
behind unless it has run qualification procedure?

   1) If there is an entry for that IPv6 address in the list of peers,
   and if the status of the entry is set to "trusted", the IPv6 packet
   should be sent over UDP to the mapped IPv4 address and mapped UDP
   port of the entry. The client updates the date of last transmission
   in the peer entry.

==> hmm.. could the list of peers information be stale, or is it 
purged often enough so that if the NAT mapping of a host changes, 
there won't be communication with it directly?  Are there fallbacks?

   Then, the Teredo relay examines whether the IPv6 source address is a
   valid Teredo address, and if the mapped IPv4 address and mapped port
   match the IPv4 source address and port number from which the packet
   is received. If this is not the case, the packet is silently
   discarded.

==> I've trouble figuring out how this would work -- maybe I'm
confused.  I mean, when the Teredo client sends toward different IPv4 
destination addresses, new mappings are created in the NAT for each -- 
and this is by definition different from the one which is learned by 
the Teredo client from the Teredo Server?

  Finally, the relay examines the destination IPv6 address. If the
   destination is the "all nodes multicast address", the packet should
   be processed locally. 

==> why this rule?

   The dual-role of server and relays implies an additional complexity
   for the programming of servers: the processing of incoming packets
   should be a combination of the server processing rules defined in
   5.3.1, and the relay processing rules defined in 5.4.2.

==> this text is not clear enough on whether section 5.3 on Teredo 
servers already includes all the functionalitty required of Teredo 
servers + relays, or whether you need to combine 5.3+5.4 to get 
server+relay?

Most Teredo servers
   will not be expected to operate more than a few years, perhaps until
   at most 2006.

==> umm, isn't this awfully optimistic? :)

   The very purpose of the Teredo service is to make a machine
   reachable through IPv6. By definition, the machine using the 
service
   will give up whatever "firewall" service was available in the NAT
   box; all services declared locally will become potential target of
   attacks from the entire IPv6 Internet. This may sound scary, but
   there are three mitigating factors.
                                                                                                  
==> "all services declared locally" is a bit short, maybe spell it
out?  Maybe also missing a word or two?

   The first mitigating factor is the possibility to restrict some
   services to only accept traffic from one of the limited address
   scopes defined in IPv6, e.g. link-local or site-local.

==> using link-locals w/ apps is IMHO pretty bad practice, and 
site-locals are gone.  please update :)

There is no
   support for such scopes in Teredo, which implies that limited-scope
   services will not be accessed through Teredo, and will be 
restricted
   to whatever other IPv6 connectivity may be available, e.g. direct
   traffic with neighbors on the local link, behind the NAT.

==> these also have teredo addresses, which go through the teredo 
server, etc. -- not from the same namespace, unless you configure them 
manually or using some other process..

   The third mitigating factor, already noted, is the availability of
   end-to-end connectivity, which allows for deployment of IP security
   services such as IKE, AH or ESP. Using these services in 
conjunction
   with Teredo is a good policy, as it will protect the client from
   possible attacks in intermediate servers such as the NAT, the 
Teredo
   server, or the Teredo relay.

==> when you use these magic keywords, one must always ask, "OK, how 
do you do key distribution?"   Not practical in many cases, I guess.

Meta-issue here: opportunistic IPsec might leverage DNS records for 
storing the keys; I think Teredo doesn't support setting reverse DNS 
records at the moment. (Which maybe for the best, considering how 
often the addresses would probably change..)

  The goal of the Teredo service is to provide hosts located behind a
   NAT with a globally reachable IPv6 address. There is a possible
   class of attacks against this service in which an attacker somehow
   intercepts the router solicitation, responds with a spoofed router
   advertisement, and provides a Teredo client with an incorrect
   address.

==> actually, a more typical attack would be the attacker guessing the
server address (simple if there are only a few of those), and the IPv4
address/port of the destination.  Then, by appropriate spoofing, a RA
could be injected without getting hold of the RS's.  Of course, this
is practically impossible if the Authentication option (just using the
nonces is enough) is included.

   The secure qualification procedure described in section 5.2.2
   enables a good protection against attacks in which a third party
   tries to spoof the server.

==> how would that secret (if you don't use just nonces) is 
distributed?  Especially if the server is hosted by someone you don't 
have a direct relationship with, you could be in trouble..

protect
   against this attack, the secret shared between client and server
   should be provisioned by an automatic procedure and contain
   sufficient entropy.

==> what are you referring to with "automatic procesdure"?  1) 
automatic distribution, or 2) automatic generation of secrets (trying 
ot ensure they have good enough entropy, e.g., are subject to e.g., 
disctionary attacks) ?

==> I'd again want to note, that using null ID and null 
authentication, could still give you the 64bit protection using nonces 
-- which is not bad for a use case like this.

==> the authentication encapsulation does not provide replay 
protection, at least as specified, but some of this could be fixed I 
guess?

   1) Client prepares router solicitation, including authentication
   header.

==> s/header/encapsulation/ (or something, to make sure this is not 
IPsec AH)

7.3.2   Denial of service by exceeding the number of peers
                                                                                             
   A Teredo client manages a cache of recently-used peers, which makes
   it stateful.

==> this is a problem of Teredo relay as well, right? 

   The ICMP Traceback (ITRACE) working group is considering systems 
for
   "tracing" the source of DOS attacks. According to the proposal, 
when
   forwarding packets, routers can, with a low probability, generate a
   Traceback message that is sent along to the destination; with 
enough
   Traceback messages from enough routers along the path, the traffic
   source and path can be determined. This set up assumes that the
   source and destination are both using the same version of IP. In 
the
   Teredo case, the ICMP Traceback packets will be sent to the Teredo
   server, not the final destination. It is conceivable to "map" the
   IPv4 traceback to an IPv6 traceback sent by the Teredo server; the
   details of the solution should be specified by the ITRACE working
   group.

==> unfortunately, the ITRACE WG was closed, and the spec is pretty 
much dead.. so I don't think we can count on this anymore. (The same 
issue later in the spec again)

   The exit strategy is facilitated by the nature of Teredo, which
   provides an IP level solution. IPv6 aware applications do not have
   to be updated to use or not use Teredo. The absence of impact on 
the
   applications makes it easier to migrate out of Teredo: network
   connectivity suffices.

==> The clients migrate out of Teredo, that's correct, but the actual 
problem is how do you retire (host-side, "local") relays?  As long as 
there are Teredo hosts out there (10 years from now on?) having such a 
feature on the box would be useful (with some definition of useful).  
What's the exit strategy for these?























editorial
---------

   We propose here a service that enables nodes located behind one or
   several IPv4 NATs to obtain IPv6 connectivity by tunneling packets
 
==> s/one or several/one or more/ (isn't this the more common usage) ?
(this is in very many places)

   several NATs; it also supposes that we can find a way to bypass the
   various "per destination protections" that many NATs implement. In
 
==> add a reference here to section 3.1?

   The specification is organized as follow. Section 2 contains the
 
==> s/follow/follows/

2.1     Teredo service
                                                                                                                  
==> 16 subsections, none of which is longer than 1 paragraph, one for
each term -- they explode the ToC.  Maybe remove the subsections and 
put these in the body of section 2, otherwise identically?

   A node that has some access to the IPv4 Internet and that wants to
   gain access to the IPv6 Internet.

==> remove redundant "that" (the same in a few other examples as well) 
?

2.10    Teredo mapped address and Teredo mapped port
                                                                                                                  
   A global IPv4 address and a UDP port that results from the
   translation by one or several NATs of the IPv4 address and UDP port
   of a client's Teredo service port.

==> suggest rewording e.g. to be like:

2.10    Teredo mapped address and Teredo mapped port
                                                                                                                  
   A global IPv4 address and a UDP port that result from the
   translation of the client's IPv4 address and Teredo service port by 
   one or more NATs.

...

   of 30 seconds; a longer value may be determined by local tests,
   described in section 5.

==> s/described/as described/

   Relaying packets over TCP would be possible, but would result in a
   very poor quality of service; relaying over UDP is a better choice.

==> s/relaying/encapsulation/

   on the specified port for a "lifetime" period. The Teredo client
   that want to maintain a mapping open in the NAT will have to send
 
==> s/want/wants/

   when no traffic is observed is observed on the connection for a
 
==> remove extra "is observed"

   transition schemes designed by the NGTRANS working group. This
 
==> v6ops now?

   - Client IPv4: the obfuscated "mapped IPv4 address" of a client
                                                                                                                  
==> s/a client/the client/

   There are thus two valid values of the Flags field: "0x0000" (all
   null) if the cone bit is set to 0, and "0x8000" if the cone bit is
   set to 1.
                                                                                                                  
==> remove "valid" or even state like "two currently specified values" 
.. just to spell it out there might be more in the future.

   A third party sends IPv6 packets to a Teredo client by sending these
   packets over UDP to the mapped IPv4 address and port of the client
   if the cone bit is set, or if the third party has recently received
   direct traffic from the client. In the other cases, the third party
   will have to first synchronize with the client, by sending an
   initial bubble through the server.

==> this seems to be mostly outside the scope of Teredo address 
specification, so one should either remove it or add references to the 
fuller specification later on in the draft.

5.1.1   Teredo IPv6 packets encapsulation
                                                                                                                 
==> s/packets/packet/

  +--------+--------+--------+--------+
  |  0x00  | 0x01   | ID-len | AU-len |
  +--------+--------+--------+--------+
  |  Client identifier (ID-len        |
  +-----------------+-----------------+
  |  octets)        |  Authentication |
  +-----------------+--------+--------+
  | value (AU-len octets)    | Nonce  |
  +--------------------------+--------+
  | value (8 octets                   |
  +--------------------------+--------+
  |                          | Conf.  |
  +--------------------------+--------+

==> I'd really try to aim for using the typical "nice" figures such as 
the the ones used in RFC2461, RFC2463, etc.

the client may use the
   Teredo service port to transmit and receive IPv6 packets, according
   to the transmission and reception procedures; these procedures use
   the "list of recent peers". For each peer, the list contains:

==> s/; t/. T/ ?

          +----+----+
          | Set C=1 |
          +----+----+

==> make more explicit that C means Cone bit?

        /---------\ Timer |                             ^
          |Starting |-------+ N attempts /----------\ Yes |
          \---------/------------------->| C == 1 ? |-----+
               | Response                \----------/
 
==> does "N attempts" refer to moving from "Starting" to "Start", or 
to "C == 1?" state?  Maybe reorganize the text a bit?

         /-----------------\
          | Restricted NAT  |
          \-----------------/

==> restricted cone NAT you mean?

   When the interface is initialized, the system first performs the
   "start action" by sending a Router Solicitation message, as defined
   in [RFC2461]. The client picks a link-local address and uses it as
   the IPv6 source of the message; the "cone" bit in the address is set
   to 1;

==> maybe refer to sect 4?

 3) If the source IPv6 address is a Teredo address, the client
   compares the mapped IPv4 address and mapped port in the source
   address with the source IPv4 address and source port of the packet.

==> s/source address/IPv6 source address/ ?

  and local peer port parameters to reflect the IPv4 source address
   and UDP source port of the bubble the last reception date to the
 
==> s/bubble/bubble,/

   When it wants to send a packet to an IPv6 node on the IPv6 Internet,
   the client should check whether a valid peer entry already exists
 
==> swap "it" and "the client" here.

   destination. The ICMPv6 packet will then be sent encapsulated in a
   UDP packet bound to the local server IPv4 address, and to the Teredo
    port. The rules of section 5.2.3 specify how the reception of this
   packet will be processed.
                                                                                                  

==> s/bound/destined/ ?
==> s/local server IPv4/Teredo server/ ?
==> s/reception of/reply to/ ?

   It is in many cases possible to work around the limitations of 
these
 
==> s/It is in many cases/In many cases, it is/ ?

  - The source IPv4 address is the server's IPv4 address.
                                                                                                  
==> s/server's IPv4/Teredo server/ (same in a couple of other places)

If the cone bit of the
   client's IPv6 address is set to 1, the RA must be sent from a
   different IPv4 source address than the server address over which the
   RS was received; if the cone bit is set to zero, the response must
   be sent back from the same address.

==> this has some operationa requirements (i.e., the server having 
more than one address), which should be spelled out (already commented 
for section 5.3)

   Teredo relays are IPv6 routers that advertise reachability of the
   Teredo service IPv6 prefix through the IPv6 routing protocols.

==> or not, in the case of local relays..

   When a Teredo relay has to transmit a packet to a Teredo client, it
   examines the destination IPv6 address. By definition, the Teredo
   relays will only send over UDP IPv6 packets whose IPv6 destination
   address is a valid Teredo IPv6 address. Before processing these
   packets, the Teredo Server MUST check that the IPv4 destination
 
==> split a new paragraph before "Before" ?

   It may be desirable in some cases to deploy stateful tunnel servers
   instead of the stateless Teredo servers. Tunnels servers generally
 
==> s/Tunnels/Tunnel/

   capacity. In summary, the attack is very hard to mount, and the 
gain
   for the attacker is minimal.

==> s/gain/additional gain/ ?

   its IPv6 traffic, using IPSEC. Even if the IPv4 and UDP headers are
   vulnerable, the use of IPSEC will effectively prevent spoofing and
 
==> s/IPSEC/IPsec/ (everywhere)

8.3.1   Denial of service by server spoofing
                                                                                             
   In section 8.2, we discussed the use of spoofed router
 
==> s/8.3/7.3/, s/8.2/7.2/ ?

   non existing IPv4 address or to the IPv4 address of a third party.
                                                                                             
==> s/non/non-/

7.4.1   Laundering DOS attacks from IPv4 to IPv4
                                                                                             
==> s/DOS/DoS/

  on their treatment of UDP; the mappings need to be continuously
   refreshed, while the ; and addressing structure may cause some 
hosts
 
==> something missing around ";"