RFC 6081

Teredo Extensions

๐Ÿ“… published January 2011, from ietf

Part 1 of 14 ๐ŸŽ€ okay bestie, let's get into RFC 6081: Teredo Extensions ๐Ÿฆ‹

The title block is giving main character energy โœจ D. Thaler wrote it at Microsoft, and it's dated January 2011. It's a Standards Track document, so it's an official Internet standard, not just an idea floating around ๐Ÿ’… It updates RFC 4380, which is the original Teredo spec, so this one is building on top of that. The header doesn't list anything it obsoletes. The ISSN is 2070-1721 ๐ŸŒธ

Abstract

okay so the abstract is the quick pitch ๐Ÿ’– This doc specifies a set of extensions to the Teredo protocol. Those extensions give Teredo new abilities, like supporting more kinds of Network Address Translations (NATs) and making communication more efficient ๐Ÿš€ literally the upgrade pack we all need ๐Ÿซถ

Status of This Memo

this section is the official paperwork ๐Ÿ“œ It's an Internet Standards Track document. It's a product of the Internet Engineering Task Force (IETF), it represents the consensus of the IETF community, it got public review, and the Internet Engineering Steering Group (IESG) approved it for publication. If you want more on how Internet Standards work, check Section 2 of RFC 5741 ๐Ÿงš You can find the current status, errata, and feedback info at http://www.rfc-editor.org/info/rfc6081

more legal vibes, but it's important ๐Ÿ™ˆ Copyright is (c) 2011 IETF Trust and the document authors, all rights reserved. This doc is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) as of the publication date. Read those carefully, because they spell out your rights and restrictions. If you pull Code Components out of this document, they have to include Simplified BSD License text, as described in Section 4.e of the Trust Legal Provisions. They also come without warranty, as the Simplified BSD License describes ๐Ÿ”ฅ

Table of Contents

here's the map of the whole doc ๐Ÿ—บ๏ธ

   1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  3
   2.  Terminology  . . . . . . . . . . . . . . . . . . . . . . . . .  3
   3.  Overview . . . . . . . . . . . . . . . . . . . . . . . . . . .  6
     3.1.  Symmetric NAT Support Extension  . . . . . . . . . . . . .  9
     3.2.  UPnP-Enabled Symmetric NAT Extension . . . . . . . . . . . 11
     3.3.  Port-Preserving Symmetric NAT Extension  . . . . . . . . . 13
     3.4.  Sequential Port-Symmetric NAT Extension  . . . . . . . . . 14
     3.5.  Hairpinning Extension  . . . . . . . . . . . . . . . . . . 15
     3.6.  Server Load Reduction Extension  . . . . . . . . . . . . . 17
   4.  Message Syntax . . . . . . . . . . . . . . . . . . . . . . . . 18
     4.1.  Trailers . . . . . . . . . . . . . . . . . . . . . . . . . 18
     4.2.  Nonce Trailer  . . . . . . . . . . . . . . . . . . . . . . 19
     4.3.  Alternate Address Trailer  . . . . . . . . . . . . . . . . 19
     4.4.  Neighbor Discovery Option Trailer  . . . . . . . . . . . . 20
     4.5.  Random Port Trailer  . . . . . . . . . . . . . . . . . . . 21
   5.  Protocol Details . . . . . . . . . . . . . . . . . . . . . . . 22
     5.1.  Common Processing  . . . . . . . . . . . . . . . . . . . . 22
       5.1.1.  Refresh Interval . . . . . . . . . . . . . . . . . . . 22
       5.1.2.  Trailer Processing . . . . . . . . . . . . . . . . . . 23
     5.2.  Symmetric NAT Support Extension  . . . . . . . . . . . . . 23
       5.2.1.  Abstract Data Model  . . . . . . . . . . . . . . . . . 24
       5.2.2.  Timers . . . . . . . . . . . . . . . . . . . . . . . . 24
       5.2.3.  Initialization . . . . . . . . . . . . . . . . . . . . 24
       5.2.4.  Message Processing . . . . . . . . . . . . . . . . . . 24
     5.3.  UPnP-Enabled Symmetric NAT Extension . . . . . . . . . . . 25
       5.3.1.  Abstract Data Model  . . . . . . . . . . . . . . . . . 26
       5.3.2.  Timers . . . . . . . . . . . . . . . . . . . . . . . . 26
       5.3.3.  Initialization . . . . . . . . . . . . . . . . . . . . 27
       5.3.4.  Message Processing . . . . . . . . . . . . . . . . . . 28
       5.3.5.  Shutdown . . . . . . . . . . . . . . . . . . . . . . . 29
     5.4.  Port-Preserving Symmetric NAT Extension  . . . . . . . . . 30
       5.4.1.  Abstract Data Model  . . . . . . . . . . . . . . . . . 30
       5.4.2.  Timers . . . . . . . . . . . . . . . . . . . . . . . . 31
       5.4.3.  Initialization . . . . . . . . . . . . . . . . . . . . 32
       5.4.4.  Message Processing . . . . . . . . . . . . . . . . . . 32
     5.5.  Sequential Port-Symmetric NAT Extension  . . . . . . . . . 35
       5.5.1.  Abstract Data Model  . . . . . . . . . . . . . . . . . 35
       5.5.2.  Timers . . . . . . . . . . . . . . . . . . . . . . . . 36
       5.5.3.  Initialization . . . . . . . . . . . . . . . . . . . . 37
       5.5.4.  Message Processing . . . . . . . . . . . . . . . . . . 37
     5.6.  Hairpinning Extension  . . . . . . . . . . . . . . . . . . 39
       5.6.1.  Abstract Data Model  . . . . . . . . . . . . . . . . . 39
       5.6.2.  Timers . . . . . . . . . . . . . . . . . . . . . . . . 39
       5.6.3.  Initialization . . . . . . . . . . . . . . . . . . . . 39
       5.6.4.  Message Processing . . . . . . . . . . . . . . . . . . 40

     5.7.  Server Load Reduction Extension  . . . . . . . . . . . . . 41
       5.7.1.  Abstract Data Model  . . . . . . . . . . . . . . . . . 41
       5.7.2.  Timers . . . . . . . . . . . . . . . . . . . . . . . . 41
       5.7.3.  Initialization . . . . . . . . . . . . . . . . . . . . 42
       5.7.4.  Message Processing . . . . . . . . . . . . . . . . . . 42
   6.  Protocol Examples  . . . . . . . . . . . . . . . . . . . . . . 42
     6.1.  Symmetric NAT Support Extension  . . . . . . . . . . . . . 42
     6.2.  UPnP-Enabled Symmetric NAT Extension . . . . . . . . . . . 45
     6.3.  Port-Preserving Symmetric NAT Extension  . . . . . . . . . 47
     6.4.  Sequential Port-Symmetric NAT Extension  . . . . . . . . . 51
     6.5.  Hairpinning Extension  . . . . . . . . . . . . . . . . . . 54
     6.6.  Server Load Reduction Extension  . . . . . . . . . . . . . 57
   7.  Security Considerations  . . . . . . . . . . . . . . . . . . . 58
   8.  Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 58
   9.  IANA Considerations  . . . . . . . . . . . . . . . . . . . . . 58
   10. References . . . . . . . . . . . . . . . . . . . . . . . . . . 58
     10.1. Normative References . . . . . . . . . . . . . . . . . . . 58
     10.2. Informative References . . . . . . . . . . . . . . . . . . 59

1. Introduction โœจ

okay so this is where the doc starts actually doing things ๐Ÿงš It specifies extensions to the Teredo protocol, the one defined in [RFC4380]. The extensions give Teredo extra capabilities, including support for more types of Network Address Translations (NATs) and support for more efficient communication. ๐Ÿ’œ the vibes are very "upgrade your whole Teredo experience" and I'm here for it ๐Ÿฆ‹

2. Terminology โœจ

okay bestie, this doc extends [RFC4380], so it borrows that terminology to stay consistent with it ๐Ÿซถ here's the whole vocab list, no cap, it's lowkey a lot but every word matters ๐Ÿ’…

  • Address-Restricted NAT: a restricted NAT that lets in packets from an external host's IP address X and port Y, as long as the internal host has sent a packet to IP address X, no matter the destination port ๐Ÿงฑ. In [RFC4787] terms, it's a NAT with Endpoint-Independent Mapping and Address-Dependent Filtering.
  • Address-Symmetric NAT: a symmetric NAT with multiple external IP addresses that gives out different IP addresses and ports for different external hosts ๐ŸŒ€
  • Cone NAT: a NAT that sends every request from the same internal IP address and port out with the same external IP address and port ๐Ÿ“ Any external host can also send a packet to the internal host just by sending it to that mapped address and port. In [RFC4787] terms, it's a NAT with Endpoint-Independent Mapping and Endpoint-Independent Filtering. the chaos-free king ๐Ÿ‘‘
  • Direct Bubble: a Teredo bubble sent straight to the IPv4 node whose Teredo address is in the Destination field of the IPv6 header, as described in Section 2.8 of [RFC4380] โœจ The IPv4 Destination Address and UDP Destination Port fields hold a mapped address/port.
  • Echo Test: a mechanism that predicts the mapped address/port a sequential port-symmetric NAT is using for a client behind it ๐Ÿ”ฎ
  • Hairpinning: a feature some NATs have where two or more hosts sit behind the same NAT and each one gets its own external (public) address and port ๐ŸŒˆ With hairpinning, those hosts can send packets to the external address and port of another host, and the NAT routes the packet right back to the correct host. The name comes from how the packet arrives on, and gets sent back out of, the same NAT interface. it's giving boomerang ๐Ÿชƒ
  • Indirect Bubble: a Teredo bubble sent indirectly (through the destination's Teredo server) to another Teredo client, as described in Section 5.2.4 of [RFC4380] ๐Ÿฆ‹
  • Local Address/Port: the IPv4 address and UDP port a Teredo client sends Teredo packets from ๐Ÿ  [RFC4380] calls the local port the Teredo service port. A node's local address might or might not be globally routable, since the node can be hiding behind one or more NATs.
  • Mapped Address/Port: a global IPv4 address and UDP port that comes from one or more NATs translating a node's own local address/port ๐Ÿ—บ๏ธ The node learns these values through the Teredo protocol, as described in [RFC4380]. For symmetric NATs, the mapped address/port can be different for every peer a node tries to talk to ๐Ÿ™ˆ
  • Network Address Translation (NAT): converting between IP addresses used inside an intranet or other private network and Internet IP addresses ๐Ÿ”
  • Nonce: a time-variant random value used during connection setup to prevent message replay and other types of attacks ๐Ÿ›ก๏ธ
  • Peer: a Teredo client that another Teredo client needs to communicate with ๐Ÿซ‚
  • Port-Preserving NAT: a NAT that translates a local address/port into a mapped address/port where the mapped port has the same value as the local port, as long as that same mapped address/port isn't already in use for a different local address/port ๐ŸŽ€
  • Port-Restricted NAT: a restricted NAT that only lets in packets from an external host's IP address X and port Y if the internal host has sent a packet to IP address X and port Y ๐Ÿ”’ In [RFC4787] terms, it's a NAT with Endpoint-Independent Mapping and Address and Port-Dependent Filtering.
  • Port-Symmetric NAT: a symmetric NAT with only one external IP address, so it only gives out different ports for different external hosts ๐ŸŽฏ
  • Private Address: an IPv4 address that isn't globally routable but sits in the private address space described in Section 3 of [RFC1918] ๐Ÿก
  • Public Address: an external global address used by a NAT ๐ŸŒ
  • Restricted NAT: a NAT where every request from the same internal IP address and port gets mapped to the same external IP address and port. Unlike a cone NAT, an external host can only send packets to an internal host (by sending to the external mapped address and port) if the internal host has already sent a packet to that external host first ๐Ÿšช There are two kinds: address-restricted NATs and port-restricted NATs.
  • Sequential Port-Symmetric NAT: a port-symmetric NAT that hands out external ports in order for every {internal IP address and port, destination IP address and port} tuple ๐Ÿ”ข The delta used in that sequential assignment is usually 1 or 2 for most of these NATs.
  • Symmetric NAT: a NAT where every request from the same internal IP address and port to the same destination IP address and port gets mapped to the same external IP address and port ๐Ÿชž Requests from the same internal IP address and port to a different destination might get a different external IP address and port. Also, a symmetric NAT only accepts packets from an external host's IP address X and port Y if some internal host has sent packets to IP address X and port Y. In [RFC4787] terms, this is a NAT with a mapping behavior of either Address-Dependent Mapping or Address- and Port-Dependent Mapping, and a filtering behavior of either Address-Dependent Filtering or Address- and Port-Dependent Filtering ๐Ÿงฉ
  • Teredo Bubble: a Teredo control message (specified in Section 2.8 of [RFC4380]) used to create a mapping in a NAT ๐Ÿซง There are two types: direct bubbles and indirect bubbles.
  • Teredo Client: a node that can reach the IPv4 Internet and wants to get onto the IPv6 Internet using the Teredo protocol ๐ŸŒ‰
  • Teredo IPv6 Address: an IPv6 address of a Teredo client, as specified in Section 2.14 of [RFC4380] ๐Ÿชช
  • Teredo Secondary Server Address: a secondary IPv4 address of a Teredo server that a Teredo client is configured with, as specified in Section 5.2 of [RFC4380] ๐Ÿฅˆ
  • Teredo Server: a node with a globally routable address on the IPv4 Internet that helps Teredo clients get IPv6 connectivity ๐Ÿฆธ
  • Teredo Server Address: the (primary) IPv4 address of a Teredo server that a Teredo client is configured with, as specified in Section 5.2 of [RFC4380] ๐Ÿฅ‡
  • UPnP-enabled NAT: a NAT that has the UPnP device control protocol enabled, as specified in [UPNPWANIP]. (Note that today, by default, most UPnP-capable NATs have the UPnP device control protocol disabled.) ๐Ÿ™ƒ

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 [RFC2119] ๐Ÿ“–


3. Overview ๐ŸŒธ

okay so the Teredo protocol (from [RFC4380]) lets nodes stuck behind one or more IPv4 NATs get IPv6 connectivity by tunneling packets over UDP ๐Ÿฆ‹

When a node behind a NAT wants to talk to a peer (aka another node) that's also behind a NAT, there are four IPv4 address/port pairs that matter ๐Ÿ‘€

  • The node's own IPv4 address/port.
  • The external IPv4 address/port that the node's NAT translates to.
  • The peer's own IPv4 address/port.
  • The external IPv4 address/port that the peer's NAT translates to.

When the node sends a packet to a peer, it sends from its own IPv4 address/port to the peer's external IPv4 address/port ๐Ÿ“ค By the time it arrives (after going through both NATs), the peer sees the packet coming from the node's external IPv4 address/port, headed to the peer's own IPv4 address/port. it's giving a whole relay race ๐Ÿƒโ€โ™€๏ธ๐Ÿ’จ

In this doc, local address/port means a Teredo client's own IPv4 address/port, and mapped address/port means the external IPv4 address/port its NAT translates the local address/port to ๐Ÿ—บ๏ธ So the mapped address/port is what the IPv4 Internet actually sees the Teredo client as.

A Teredo client talks to a Teredo server to find out its mapped address/port ๐Ÿ” The mapped address/port, together with the Teredo server address, gets used to make an IPv6 address called a Teredo IPv6 address. This means any peer that has the node's IPv6 address can easily figure out which external IPv4 address/port to send IPv6 packets to, wrapped in IPv4 UDP messages ๐Ÿ’Œ

This document specifies extensions to the Teredo protocol โœจ These Teredo extensions are independent of each other and can be implemented in isolation, with one exception: the UPnP-Symmetric NAT Extension and the Port-Preserving Symmetric NAT Extension both require the Symmetric NAT Support Extension to be implemented ๐Ÿซถ An implementation of this spec can support any combination of the Teredo extensions, as long as that one restriction is respected ๐Ÿ’…

The following matrix shows the connectivity improvements some of the extensions in this doc bring ๐Ÿ“Š Read it as Source NAT down the side, Destination NAT across the top, and check what each pairing gets you ๐Ÿ‘‘

                             Destination NAT
          |      |      |      |      |      | Port-|      |      |
          |      |      |      | UPnP | UPnP | pres.| Seq. |      |
          |      | Addr.| Port | Port | Port | Port-| Port-| Port-| Addr
Source NAT| Cone | rest.| rest.| rest.| symm.| symm.| symm.| symm.| symm
----------+------+------+------+------+------+------+------+------+-----
Cone      |  Yes |  Yes |  Yes |  Yes |  SNS |  SNS |  SNS |  SNS |  SNS
----------+------+------+------+------+------+------+------+------+-----
Address   |  Yes |  Yes |  Yes |  Yes |  SNS |  SNS |  SNS |  SNS |  No
restricted|      |      |      |      |      |      |      |      |
----------+------+------+------+------+------+------+------+------+-----
Port      |  Yes |  Yes |  Yes |  Yes |  No  | SNS+ | SNS+ |  No  |  No
restricted|      |      |      |      |      |  PP  |  SS  |      |
----------+------+------+------+------+------+------+------+------+-----
UPnP Port-|  Yes |  Yes |  Yes |  Yes | SNS+ |  No  |  No  |  No  |  No
restricted|      |      |      |      | UPnP |      |      |      |
----------+------+------+------+------+------+------+------+------+-----
UPnP Port |  SNS |  SNS |  No  | SNS+ | SNS+ |  No  |  No  |  No  |  No
symmetric |      |      |      | UPnP | UPnP |      |      |      |
----------+------+------+------+------+------+------+------+------+-----
Port-     |      |      |  SNS |      |      |  SNS |  SNS |      |
preserving|  SNS |  SNS |   +  |  No  |  No  |   +  |   +  |  No  |  No
Port-     |      |      |  PP  |      |      |  PP  |  SS  |      |
symmetric |      |      |      |      |      |      |      |      |
----------+------+------+------+------+------+------+------+------+-----
Sequential|      |      |  SNS |      |      |      |      |      |
Port-     |  SNS |  SNS |   +  |  No  |  No  |  No  |  No  |  No  |  No
symmetric |      |      |  SS  |      |      |      |      |      |
----------+------+------+------+------+------+------+------+------+-----
Port-     |  SNS |  SNS |  No  |  No  |  No  |  No  |  No  |  No  |  No
symmetric |      |      |      |      |      |      |      |      |
----------+------+------+------+------+------+------+------+------+-----
Address-  |  SNS |  No  |  No  |  No  |  No  |  No  |  No  |  No  |  No
symmetric |      |      |      |      |      |      |      |      |
     Yes = Supported by [RFC4380].

     SNS = Supported with the Symmetric NAT Support Extension.

SNS+UPnP = Supported with the Symmetric NAT Support Extension and UPnP
           Symmetric NAT Extension.

  SNS+PP = Supported with the Symmetric NAT Support Extension and Port-
           Preserving Symmetric NAT Extension.

  SNS+SS = Supported with the Symmetric NAT Support Extension and
           Sequential Port-Symmetric NAT Extension.

      No = No connectivity.

Figure 1: Matrix of Connectivity Improvements for Teredo Extensions ๐Ÿฆ‹

Okay bestie, big note ๐Ÿ“ โ€” just like with [RFC4380], if the qualification process doesn't work out, Teredo won't get an IPv6 address ๐Ÿ™ˆ and your connectivity just acts like Teredo was never there. ๐Ÿ’€ Same deal for any NAT combo that Teredo and these extensions don't cover: the connectivity tests between a client and its peer will fail within a finite period of time ๐Ÿซถ, which lets the client handle it like any other unreachable destination address (for example, by trying another address of the destination, like a native IPv4 address) โœจ.

3.1. Symmetric NAT Support Extension ๐Ÿ’–

The qualification procedure (as specified in Section 5.2.1 of [RFC4380]) is the process that lets a Teredo client figure out what kind of NAT it's sitting behind ๐Ÿ”, plus its mapped address/port as seen by its Teredo server. Slay. ๐Ÿ’… But here's the tea: Section 5.2.1 of [RFC4380] suggests that if the client finds out it's behind a symmetric NAT, it should go into an "offline state" where it can't use Teredo at all ๐Ÿ˜ญ. The main reason is that Teredo clients have a really hard time connecting to each other when either one of them (or both) is behind a symmetric NAT ๐Ÿฅบ. Because of how a symmetric NAT works, a peer sees a different mapped address/port in the IPv4/UDP headers of packets coming from a Teredo client than the one the node's Teredo server sees (and that's the one embedded in the node's Teredo IPv6 address) ๐ŸŒˆ. So a symmetric NAT won't let in incoming packets from a peer that are addressed to the mapped address/port embedded in the node's Teredo IPv6 address. The packets get dropped, and communication with Teredo clients behind symmetric NATs just never gets established. Iconic behaviour, not in a good way ๐Ÿ’€.

With the Symmetric NAT Support Extension, Teredo clients keep using Teredo even after they figure out they're behind a symmetric NAT โœจ๐ŸŽ€. Main character energy ๐Ÿ‘‘.

Let's look at the topology in Figure 2. Teredo Client B uses Teredo Server 2 to learn that its mapped address/port is 192.0.2.10:8192, and then builds a Teredo IPv6 address, as specified in Section 4 of [RFC4380] ๐Ÿงš. So c633:6476 is the hexadecimal value of the address of Teredo Server 2 (198.51.100.118), the mapped port gets exclusive-OR'ed with 0xffff to form dfff, and the Mapped Address gets exclusive-OR'ed with 0xffffffff to form 3fff:fdf5 ๐Ÿ“.

Teredo Client A uses Teredo Server 1 to learn that its mapped address/port is 192.0.2.1:4096 and, with this extension, builds a Teredo IPv6 address (as specified in Section 4 of [RFC4380]) even though it learns it's behind a symmetric NAT ๐Ÿซฃ. So cb00:7178 is the hexadecimal value of the address of Teredo Server 1 (203.0.113.120), the mapped port gets exclusive-OR'ed with 0xffff to form efff, and the Mapped Address gets exclusive-OR'ed with 0xffffffff to form 3fff:fdfe ๐ŸŒธ.

               --------------------------------------------
              /                                            \
             <               IPv6 Internet                  >
              \                                            /
               -|----------------------------------------|-
                |                                        |
          +----------+                             +----------+
          |  Teredo  |                             |  Teredo  |
          | Server 1 |                             | Server 2 |
          +----------+                             +----------+
   203.0.113.120|                          198.51.100.118|
               -|----------------------------------------|-
              /                                            \
             <               IPv4 Internet                  >
              \                                            /
               -|----------------------------------------|-
       192.0.2.1|                              192.0.2.10|
   UDP port 4096|                           UDP port 8192|
           +---------+                             +----------+
           |Symmetric|                             |Other type|
           |   NAT   |                             |  of NAT  |
           +---------+                             +----------+
                |                                        |
       +-----------------+                      +-----------------+
       | Teredo client A |                      | Teredo client B |
       +-----------------+                      +-----------------+
2001:0:cb00:7178:0:efff:3fff:fdfe      2001:0:c633:6476:0:dfff:3fff:fdf5
          Teredo Address                           Teredo Address

Figure 2: Symmetric NAT Example ๐ŸŒˆ

This is the Symmetric NAT Support Extension in action ๐Ÿ”ฅ. It lets a Teredo client behind a symmetric NAT talk to Teredo peers behind cone or address-restricted NATs, and how it goes depends on who starts the conversation ๐Ÿ’ฌ.

In the first case, say a Teredo Client B (B) behind a cone or address-restricted NAT starts talking to Teredo Client A (A), who's behind a symmetric NAT. B sends an indirect bubble to A through A's server (Teredo Server 1), and A replies with a direct bubble ๐Ÿซง. That direct bubble gets to B because B is behind a cone or address-restricted NAT โœจ. The catch is that the mapped address/port in the IPv4/UDP headers of the direct bubble is different from the mapped address/port embedded in A's Teredo IPv6 address ๐Ÿ‘€. So B remembers the mapped address/port of the direct bubble and uses it for future communication with A, and just like that, communication is established ๐Ÿฅณ.

In the second case, A, behind a symmetric NAT, starts talking to B, who's behind a cone or address-restricted NAT. A sends an indirect bubble to B through B's server (Teredo Server 2), and B replies with a direct bubble ๐Ÿ“จ. This direct bubble gets dropped by A's symmetric NAT ๐Ÿ˜ญ, because it's addressed to the mapped address/port embedded in A's Teredo IPv6 address. Don't panic though: communication can still be established if B responds with an indirect bubble through A's server (Teredo Server 1) ๐Ÿฆ‹. Now the scenario looks just like the first case, and communication gets established too ๐Ÿ’–.

3.2. UPnP-Enabled Symmetric NAT Extension โœจ

Okay so this one is built on top of the Symmetric NAT Support Extension ๐Ÿ’– It only actually helps with UPnP-enabled Symmetric NATs if Teredo clients are already allowed to get a Teredo IPv6 address even though they're stuck behind a symmetric NAT. No cap, the order matters ๐ŸŽ€

The Symmetric NAT Support Extension lets Teredo clients behind symmetric NATs talk to clients behind cone NATs or address-restricted NATs. BUT (and this is the sad part ๐Ÿ˜ญ) clients behind symmetric NATs still can't talk to clients behind port-restricted NATs or to other symmetric NATs.

Let's go back to Figure 2 (see Section 3.1) ๐ŸŒธ Say Teredo Client A is behind a symmetric NAT and wants to talk to Client B, who is behind a port-restricted NAT. Client A sends a direct bubble and an indirect bubble to Client B through Client B's server (Teredo Server 2). Because of how symmetric NATs work, the IPv4 source of that direct bubble has a different mapped address and/or port than the one embedded in the Teredo server. The direct bubble gets dropped, since Client B's NAT has no state to let it through, and Client B never learns the mapped address/port that showed up in the IPv4/UDP headers. ๐Ÿ’€

Then the indirect bubble from Client A reaches Client B, and Client B sends back a direct bubble aimed at the mapped address/port embedded in Client A's Teredo IPv6 address. This one gets dropped too, because Client A's NAT has no state to accept packets for that mapped address/port. BUT the direct bubble still does something useful: it makes Client B's NAT set up outgoing state for the mapped address/port embedded in Client A's Teredo IPv6 address ๐Ÿฆ‹

As described in Section 3.1, Client B also sends an indirect bubble that gets a direct bubble back from Client A. Unlike the Section 3.1 situation, this direct bubble from Client A gets dropped, because Client B's NAT has no state for the mapped address/port that Client A's NAT is using. Here's the tea: Client B's NAT is port-restricted, so it needs both the mapped address AND the port to match its outgoing state. In Section 3.1, Client A's NAT was a cone or address-restricted NAT, which only needed the mapped address (not the port) to match. So Client A and Client B can't connect ๐Ÿ˜ญ And if Client B were behind a symmetric NAT instead, it gets even messier, because Client B's NAT would use a different outgoing mapped address/port than the one embedded in Client B's Teredo IPv6 address ๐Ÿ’…

Now for the fix ๐ŸŽ€ If a Teredo client is separated from the global Internet by a single UPnP-enabled symmetric or port-restricted NAT, it can talk to other Teredo clients that are behind a single UPnP-enabled symmetric or port-restricted NAT, like this:

Before a Teredo client talks to the Teredo server during the qualification procedure, it uses UPnP to reserve a translation from a local address/port to a mapped address/port. So during qualification, the Teredo server reflects back that reserved mapped address/port, and it gets included in the Teredo IPv6 address. The mapping UPnP created lets the NAT forward packets destined for the mapped address/port to the local address/port, no matter where the packets came from. It usually doesn't, though, make packets sent from the local address/port get translated to show the mapped address/port as their external source. So the NAT keeps acting like a symmetric NAT in that respect ๐Ÿงš

So a Teredo client behind a UPnP-enabled symmetric NAT can receive a direct bubble from any Teredo peer. The client compares the peer's mapped address/port, as seen in the IPv4/UDP headers, with the mapped address/port in the peer's Teredo IPv6 address. If the two mappings are different, that packet came from another Teredo client behind a symmetric NAT. The Symmetric NAT Support Extension suggested using the peer's mapped address/port seen in the IPv4/UDP headers for future communication. BUT, since symmetric NAT-to-symmetric NAT communication wouldn't have worked anyway, the Teredo client sends a direct bubble back to the mapped port/address embedded in the peer's Teredo IPv6 address instead ๐Ÿ™ˆ If the peer is also behind a UPnP-enabled NAT, that direct bubble makes it through and the communication gets established โœจ

Even once communication is established between the two Teredo IPv6 addresses, the mappings are asymmetric in the two directions. Incoming packets are destined to the reserved mapped address/port embedded in the Teredo IPv6 address. Outgoing packets, on the other hand, appear to come from a different mapped address/port because of the symmetric NAT behavior ๐ŸŒˆ

3.3. Port-Preserving Symmetric NAT Extension ๐Ÿฆ‹

The Port-Preserving Symmetric NAT Extension depends on the Symmetric NAT Support Extension (Section 3.1). Same deal as before: it only helps traverse port-preserving symmetric NATs if Teredo clients are enabled to get a Teredo IPv6 address even when they're behind a symmetric NAT ๐Ÿ’œ

The Symmetric NAT Support Extension lets Teredo clients behind symmetric NATs talk to clients behind cone NATs or address-restricted NATs. Still, clients behind symmetric NATs can't talk to clients behind port-restricted or symmetric NATs, as described in Section 3.2. Also, the Port-Preserving Symmetric NAT Extension described here is independent of the UPnP-enabled Symmetric NAT Extension from Section 3.2, so they don't need each other ๐Ÿซถ

If a Teredo client is behind a port-preserving symmetric NAT, it can talk to other Teredo clients behind a port-restricted NAT or a port-preserving symmetric NAT like this:

Teredo clients compare the mapped port they learned during the qualification procedure with their local port, to figure out whether they're behind a port-preserving NAT. If the mapped port and the local port have the same value, the Teredo client is behind a port-preserving NAT. By the end of qualification, the Teredo client also knows whether it's behind a symmetric NAT, as described in Section 3.1 ๐ŸŽ€

Teredo clients behind port-preserving symmetric NATs can also listen on randomly chosen local ports. If that randomly chosen local port hasn't been used by the symmetric NAT as a mapped port in a prior port-mapping, the NAT uses the same port number as the mapped port. So the challenge is getting the first direct bubble sent out from the random port to a valid destination address and port. When the mapped address/port is embedded in the destination's Teredo IPv6 address, this is easy peasy ๐Ÿ“

It gets more complicated when the destination Teredo client is also behind a port-preserving symmetric NAT ๐Ÿ˜ญ In that case, both Teredo clients need to send their first direct bubbles to the correct destination mapped address/port. So the protocol messages that tell one Teredo client the other's random port number must be exchanged indirectly (via Teredo servers). Once one Teredo client has access to the other's random port number, it can send a direct bubble destined to the mapped address embedded in the destination's Teredo IPv6 address, and the mapped port can be the same as the destination's random port number. If both NATs are port-preserving, port-preserved mappings get created on both NATs, and the second direct bubble succeeds in reaching the destination โœจ

3.4. Sequential Port-Symmetric NAT Extension ๐Ÿ’…

The Sequential Port-Symmetric NAT Extension depends on the Symmetric NAT Support Extension (Section 3.1). This extension only helps traverse a sequential port-symmetric NAT if Teredo clients are enabled to get a Teredo IPv6 address even when they're behind a symmetric NAT ๐ŸŒธ

When the Sequential Port-Symmetric NAT Extension is in use, a Teredo client behind a sequential port-symmetric NAT can talk to other Teredo clients that are behind a port-restricted NAT, as follows:

During qualification, if the client finds out it's behind a symmetric NAT that is not port-preserving, the client assumes by default that it's behind a sequential port-symmetric NAT. This assumption is proactive, and here's why ๐Ÿ‘‘

  • There is no perfect method of discovering whether the client is behind a sequential port-symmetric NAT.
  • These kinds of NATs are notorious for changing their behavior. At times, they could be sequential port-symmetric and at other times not.
  • There is no other solution for symmetric NAT traversal, so this is a last resort.

Teredo clients behind sequential port-symmetric NATs can also listen on a randomly chosen local port when they talk to a peer. To predict the external port being used for a given peer, the client sends three packets:

  • Packet 1 is a router solicitation (as specified in Section 5.2.1 of [RFC4380]) sent to the Teredo server address.
  • Packet 2 is a direct bubble sent to the peer.
  • Packet 3 is a router solicitation sent to the secondary Teredo server address.

As part of the normal Teredo protocol, the Teredo server responds to packets 1 and 3. Based on those responses, the client now knows that Packet 1 was seen as coming from one external port, and Packet 3 was seen as coming from another external port. Assuming the NAT is a sequential port-symmetric NAT, the external port for Packet 2 is estimated (or predicted) to be midway between the external ports for Packets 1 and 3. Note that because other applications might also have been using the NAT between packets 1 and 3, the actual port might not be exactly the midpoint ๐Ÿ™ˆ

The Teredo client then tells its peer the predicted port, and the peer sends a direct bubble to that communicated port. If the communicated port really is the external port for Packet 2, the direct bubble reaches the Teredo client ๐Ÿฆ‹

3.5. Hairpinning Extension ๐ŸŽข

okay so hairpinning is the NAT doing a little loop-de-loop ๐ŸŒ€. It takes packets that a private (local) address sends to the NAT's public (mapped) address and turns them around, sending them back to another private destination behind that same NAT. If the NAT can't do this, two Teredo clients behind the same NAT literally cannot talk to each other, as laid out in Section 8.3 of [RFC4380]. way too sad ๐Ÿ˜ญ

The Hairpinning Extension lets those two clients chat even when the NAT doesn't hairpin. Here's the setup ๐Ÿ‘‡

            --------------------------------------------
           /                                            \
          <               IPv6 Internet                  >
           \                                            /
            --------------------|-----------------------
                                |
                          +----------+
                          |  Teredo  |
                          |  Server  |
                          +----------+
                   203.0.113.120|
            --------------------|-----------------------
           /                                            \
          <               IPv4 Internet                  >
           \                                            /
            --------------------|-----------------------
                  198.51.100.118|
                        NAT +-------+
                    without |  NAT  |
                hairpinning |   E   |
                    support +-------+
                                |
             +------------------+--------------------+
  192.168.1.0|                            192.168.1.1|
UDP port 4095|                          UDP port 4096|
        +---------+                            +----------+
        |   NAT   |                            |    NAT   |
        |    F    |                            |     G    |
        +---------+                            +----------+
             |                                       |
    +-----------------+                     +-----------------+
    | Teredo client A |                     | Teredo client B |
    +-----------------+                     +-----------------+
2001:0:cb00:7178:0:f000:39cc:9b89      2001:0:cb00:7178:0:efff:39cc:9b89
       Teredo Address                          Teredo Address

                    Figure 3: Hairpinning Example

So Teredo Client A (A) sends its local address/port inside the indirect bubble it sends to Teredo Client B (B). When B gets that indirect bubble, it starts trying to connect by sending direct bubbles to A's mapped address/port, and also to B's own local address/port. bestie, that's the whole trick โœจ

Now, if a Teredo client sits in a multi-NAT hierarchy and its NAT supports UPnP (as specified in [UPNPWANIP]), the client can use UPnP to find out the mapped address/port that NAT gave it. It can then include that info, along with its local address/port, in the indirect bubble. The destination client now tries to connect by sending direct bubbles to the mapped address/port inside its Teredo IPv6 address, to the local address/port in the bubble, and also to the mapped address/port in the bubble. ๐Ÿฆ‹

Quick note: UPnP support is only needed when the Teredo clients are behind different NATs in a multi-NAT hierarchy. Without UPnP, the Hairpinning Extension still lets two hosts behind the same non-hairpinning NAT talk using their Teredo IPv6 addresses. no cap, that's so clean ๐Ÿ’…


3.6. Server Load Reduction Extension ๐Ÿงš

Say a Teredo client and a Teredo peer got a connection going, but then it went quiet for a while. For efficiency, it's best to refresh the mapping state in the NATs sitting between them. To do that, the Teredo client needs to solicit a direct bubble response from the Teredo peer. Normally an indirect bubble is what solicits that direct bubble response, as specified in Section 5.2.4 of [RFC4380]. The catch? Those indirect bubbles pile up load on the Teredo server ๐Ÿ˜ฉ

The Server Load Reduction Extension fixes this by letting Teredo clients send direct bubbles most of the time, instead of sending indirect bubbles all the time. Here's how it goes:

  1. When a Teredo client tries to refresh its communication with a Teredo peer, it uses a direct bubble instead of an indirect bubble. Direct bubbles don't normally solicit a response, so the direct bubble format gets extended so it can solicit one.
  2. When a Teredo client receives a direct bubble that is soliciting a response, it responds with a direct bubble.
  3. If attempts to re-establish communication with direct bubbles fail, the Teredo client starts over the process of establishing communication with the Teredo peer, as specified in Section 5.2.4 of [RFC4380]. ๐Ÿ”

4. Message Syntax โœจ

All Teredo messages travel over the User Datagram Protocol (UDP), as specified in Section 3 of [RFC4380]. ๐Ÿ“ฆ

Section 5.2.3 of [RFC4380] also says this:

An IPv6 packet is deemed valid if it conforms to [RFC2460]: the protocol identifier should indicate an IPv6 packet and the payload length should be consistent with the length of the UDP datagram in which the packet is encapsulated. In addition, the client should check that the IPv6 destination address correspond [sic] to its own Teredo address.

This document updates the word "consistent" from that quote. Here's the new vibe ๐Ÿ’–: the IPv6 payload length counts as "consistent" with the UDP datagram length if the IPv6 packet length (that's the Payload Length value in the IPv6 header, plus the IPv6 header size) is less than or equal to the UDP payload length (that's the Length value in the UDP header, minus the UDP header size). This lets trailers come after the IPv6 packet, which we get into in the following sections. iconic ๐Ÿซถ


4.1. Trailers ๐ŸŽ€

Teredo packets can carry a variable number of type-length-value (TLV) encoded trailers. They're formatted like this (intended to be similar to the use of IPv6 options defined in [RFC2460] section 4.2):

                    1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     Type      |    Length     |        Value (variable)       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Type (1 byte): an 8-bit identifier for the type of trailer.

Length (1 byte): an 8-bit unsigned integer. It's the length of the Value field of this trailer, in octets.

Value (variable): trailer-Type-specific data.

Okay, the top two bits of each trailer Type identifier are encoded to say what to do if the host doesn't recognize that trailer Type ๐Ÿง:

  • 00, 10, 11: skip over this trailer and continue processing the packet.
  • 01: discard the packet.

4.2. Nonce Trailer ๐Ÿ”

The Nonce Trailer is used by the Symmetric NAT Support Extension (and therefore also the UPnP-enabled Symmetric NAT Extension and Port-Preserving Symmetric NAT Extension), plus the Hairpinning Extension. It can show up in both indirect and direct bubbles. The nonce in it helps authenticate a Teredo client sitting behind a Symmetric NAT. main character energy ๐Ÿ‘‘

                    1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     Type      |    Length     |             Nonce             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|              ...              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Type (1 byte): the Trailer Option type. This field MUST be set to 0x01.

Length (1 byte): the length in bytes of the rest of the option. This field MUST be set to 0x04.

Nonce (4 bytes): the nonce value.


4.3. Alternate Address Trailer ๐ŸŒธ

The Alternate Address Trailer is used by the Hairpinning Extension. It MUST NOT be present in any packets other than indirect bubbles sent by a Teredo client. Its job is to give another Teredo client behind the same NAT more address options to connect with ๐Ÿ™ˆ

                    1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     Type      |    Length     |            Reserved           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|              Alternate Address/Port List (variable)           |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Type (1 byte): the Trailer Option type. This field MUST be set to 0x03.

Length (1 byte): the length in bytes of the rest of the option. The value of this field MUST be in the range 8 to 26 (i.e., 2 bytes for the Reserved field, and 6 bytes for each entry in the Alternate Address/Port List). That allows for a minimum of one address/port mapping and a maximum of four address/port mappings to be advertised. It SHOULD be at most 14, since a maximum of two address/port mappings can be determined by Teredo: one local address/port and one obtained using UPnP. Because the length of each alternate address/port is 6 bytes, the valid range of values is only 8, 14, 20, and 26. ๐Ÿงฎ

Reserved (2 bytes): This field MUST be set to 0x0000 and ignored on receipt.

Alternate Address/Port List (variable): an array of additional address/port pairs that other Teredo clients can use to communicate with the sender. Each alternate address/port entry MUST be formatted as follows:

                    1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      IPv4 Address                             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|              Port             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

IPv4 Address (4 bytes): an IPv4 address in network byte order. This field MUST contain a valid unicast address.

Port (2 bytes): a port number in network byte order. This field MUST NOT be zero. ๐Ÿ’œ

4.4. Neighbor Discovery Option Trailer ๐Ÿฆ‹

okay so this trailer is used by the Server Load Reduction Extension, and it's giving "direct bubbles just got a glow-up" ๐Ÿ’… It lets a direct bubble carry an IPv6 Neighbor Solicitation (Section 4.3 of [RFC4861]) as well as an IPv6 Neighbor Advertisement (Section 4.4 of [RFC4861]). The big win is that packets can be sent without being relayed through a Teredo server, which is iconic ๐Ÿ˜ญ

The trailer also lets the receiver tell apart a direct bubble that's asking for a reply from a regular direct bubble ๐Ÿงš That means Teredo clients can use direct bubbles to refresh inactive connections instead of having to use indirect bubbles. Main character energy โœจ

                        1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      Type     |     Length    | DiscoveryType |   Reserved    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |              ...              |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Type (1 byte): this is the Trailer Option type. It MUST be set to 0x04. ๐Ÿ’–

Length (1 byte): the length in bytes of the rest of the option. It MUST be set to 0x04. ๐ŸŽ€

DiscoveryType (1 byte): this field MUST be set to one of the following values:

  • TeredoDiscoverySolicitation (0x00): the receiver is asked to respond with a direct bubble whose DiscoveryType is TeredoDiscoveryAdvertisement. ๐Ÿ™‹โ€โ™€๏ธ
  • TeredoDiscoveryAdvertisement (0x01): the direct bubble is a response to a direct bubble, or to an indirect bubble, that contains a DiscoveryType of TeredoDiscoverySolicitation. ๐ŸŒˆ

Reserved (3 bytes): this field MUST be set to 0x000000 on transmission and ignored on receipt. ๐ŸŒธ


4.5. Random Port Trailer ๐ŸŒธ

the Random Port Trailer is used by the Port-Preserving Symmetric NAT Extension, and it shows up in both indirect and direct bubbles ๐Ÿ“

                        1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      Type     |     Length    |          Random Port          |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Type (1 byte): this is the Trailer Option type. It MUST be set to 0x05. ๐Ÿ’–

Length (1 byte): the length in bytes of the rest of the option. It MUST be set to 0x02. ๐ŸŽ€

Random Port (2 bytes): this is the external port that the sender predicts its NAT has assigned for talking to the destination. It MUST be specified in network byte order. ๐Ÿง 


5. Protocol Details ๐Ÿ‘‘

5.1. Common Processing โœจ

this section's behaviour applies to multiple extensions, so pay attention ๐Ÿซถ

Packets that are equivalent to the ones sent for a peer the first time a connection is being established MAY be generated at other implementation-specific times. (For example, an implementation might choose to do so when its Neighbor Cache Entry for the peer is in the PROBE state.) ๐Ÿ”ฅ

5.1.1. Refresh Interval ๐ŸŒˆ

Section 5.2 of [RFC4380] says:

The client must regularly perform the maintenance procedure in order to guarantee that the Teredo service port remains usable. The need to use this procedure or not depends on the delay since the last interaction with the Teredo server. The refresh procedure takes as a parameter the "Teredo refresh interval". This parameter is initially set to 30 seconds; it can be updated as a result of the optional "interval determination procedure". The randomized refresh interval is set to a value randomly chosen between 75% and 100% of the refresh interval.

okay so this can be a problem ๐Ÿ˜ญ when the client sits behind a NAT that expires state in less than 30 seconds. The optional interval determination procedure (Section 5.2.7 of [RFC4380]) also doesn't go under 30 seconds either. So this document refines the behaviour: the initial parameter SHOULD be configurable, and the default MUST be 30 seconds. An implementation MAY set the randomized refresh interval to a value randomly chosen within an implementation-specific range, and that range MUST fall within 50% to 150% of the refresh interval. ๐Ÿ’…

Section 5.2.5 of [RFC4380] states that:

At regular intervals, the client MUST check the "date and time of the last interaction with the Teredo server" to ensure that at least one packet has been received in the last Randomized Teredo Refresh Interval. If this is not the case, the client SHOULD send a router solicitation message to the server, as specified in Section 5.2.1;

this document refines it like so: a Teredo client MAY choose to send additional router solicitation messages to the server at other implementation-specific times. (For example, an implementation might choose to do so when its Neighbor Cache Entry for the router is in the PROBE state.) ๐Ÿฆ‹

5.1.2. Trailer Processing ๐ŸŽ€

okay this part is so important, bestie ๐Ÿซถ A Teredo client MUST process the sequence of trailers in the same order as they appear in the packet. If the client doesn't recognise the trailer Type while processing the trailers in the Teredo packet, it MUST discard the packet when the highest-order bits of the trailer Type contain 01. Otherwise, the Teredo client MUST skip past the trailer. A Teredo client MUST stop processing the trailers as soon as a malformed trailer shows up in the sequence. A trailer counts as malformed if it has any of these properties:

  • The length in bytes of the remainder of the UDP datagram is less than 2 (the size of the Type and Length fields of a trailer). ๐Ÿ’€
  • The length in bytes of the remainder of the UDP datagram is less than 2 + the value of the Length field of the trailer. ๐Ÿ’€

5.2. Symmetric NAT Support Extension ๐Ÿ”ฅ

Section 5.2.1 of [RFC4380] advises that no Teredo IPv6 address be configured if the Teredo client is positioned behind a symmetric NAT. For Teredo clients behind symmetric NATs, the mapped address/port that their NAT uses when talking to a Teredo peer is different from the mapped address/port embedded in the client's Teredo IPv6 address. This extension is the fix for that mismatch ๐Ÿ’–

Section 5.2.9 of [RFC4380] also specifies a direct IPv6 connectivity test, which checks that the mapped address/port in a peer's Teredo IPv6 address isn't spoofed. It does this with a nonce in ICMPv6 Echo Request and Response messages (defined in Section 4 of [RFC4443]). The catch is that this test only works between Teredo IPv6 addresses and non-Teredo IPv6 addresses. So in this extension, we bring in a nonce for direct and indirect bubbles, and a way to verify that the mapped address/port aren't spoofed. Iconic, honestly ๐Ÿงš

This extension is optional; an implementation SHOULD support it. ๐ŸŒŸ

5.2.1. Abstract Data Model ๐Ÿง 

this section describes a conceptual model of how an implementation might organise its data to take part in this protocol. It's there to make the protocol's behaviour easier to explain. This document does not mandate that implementations follow this model, as long as their external behaviour matches what's described here ๐Ÿซถ

On top of the state specified in Section 5.2 of [RFC4380], the following are also required:

Peer Entry: the following additional state is required on a per-peer basis:

  • Nonce Sent: the value of the nonce sent in the last indirect bubble sent to the Teredo peer.
  • Nonce Received: the value of the nonce received in the last indirect bubble received from the Teredo peer.

5.2.2. Timers โฑ๏ธ

No timers are necessary other than those in [RFC4380]. ๐Ÿ’…

5.2.3. Initialization ๐ŸŒฑ

No initialization is necessary other than that specified in [RFC4380]. โœจ

5.2.4. Message Processing ๐Ÿ’Œ

Except as specified in the following sections, the rules for message processing are as specified in [RFC4380]. ๐Ÿฆ‹

5.2.4.1. Sending an Indirect Bubble ๐Ÿซง

The rules for when indirect bubbles are sent to a Teredo peer are specified in Section 5.2.6 of [RFC4380]. When a Teredo client sends an indirect bubble, it MUST generate a random 4-byte value and include it in the Nonce field of a Nonce Trailer (Section 4.2) appended to the indirect bubble. It also has to store that value in the Nonce Sent field of its Peer Entry for that Teredo peer. ๐Ÿ“

5.2.4.2. Sending a Direct Bubble ๐Ÿš€

The rules for when direct bubbles are sent to a Teredo peer are specified in Section 5.2.6 of [RFC4380]. When a Teredo client sends a direct bubble to a peer after receiving an indirect bubble with a Nonce Trailer, it MUST include in the direct bubble a Nonce Trailer with the same nonce value. ๐ŸŽ€

If the Teredo client is about to send a direct bubble before it has received an indirect bubble from the Teredo peer, the Teredo client MUST NOT include a Nonce Trailer. ๐Ÿ™…โ€โ™€๏ธ

5.2.4.3. Receiving an Indirect Bubble ๐Ÿ“ฌ

The rules for processing an indirect bubble are specified in Section 5.2.3 of [RFC4380]. On top of that, when a Teredo client receives an indirect bubble containing a Nonce Trailer, it MUST store the nonce in the Nonce Received field of its Peer Entry for that Teredo peer. If an indirect bubble arrives without a Nonce Trailer and the Nonce Received field in the Peer Entry is non-zero, the Nonce Received field SHOULD be set to zero. ๐ŸŒธ

5.2.4.4. Receiving a Direct Bubble ๐ŸŒˆ

If the mapped address/port of the direct bubble matches the mapped address/port embedded in the source Teredo IPv6 address, the direct bubble MUST be accepted, as specified in Section 5.2.3 of [RFC4380]. ๐Ÿ’–

Also, if the mapped address/port doesn't match the embedded address/port, but the direct bubble contains a Nonce Trailer with a nonce that matches the Nonce Sent field of the Teredo peer, the direct bubble MUST be accepted. ๐Ÿงš

If neither of the above conditions is true, the direct bubble MUST be dropped. ๐Ÿ’€

If the direct bubble is accepted, the Teredo client MUST record the mapped address/port that the direct bubble came from in the mapped address/port fields of the Teredo peer, as specified in Section 5.2 of [RFC4380]. ๐Ÿฆ‹


5.3. UPnP-Enabled Symmetric NAT Extension ๐Ÿ‘‘

The UPnP-enabled Symmetric NAT Extension is optional; an implementation SHOULD support it. ๐ŸŒŸ This extension depends on the Symmetric NAT Support Extension (Section 5.2). Any node that implements this extension MUST also implement the Symmetric NAT Support Extension. Dependencies are a whole vibe, but the rule is simple ๐Ÿ’…

5.3.1. Abstract Data Model โœจ

okay so this section is a conceptual model ๐Ÿง  of how an implementation could organize its data so the protocol makes sense when we explain it. you don't have to build it exactly like this, bestie, as long as your external behavior matches what this document says ๐Ÿ’…

this extension builds on the abstract data model in Section 5.2.1 and adds these fields:

UPnP-Enabled NAT flag: a Boolean, set to TRUE if the NAT in front of the Teredo client is UPnP enabled ๐ŸŽ€ the default is FALSE.

UPnP-Mapped Address/Port: the mapped address/port that the UPnP-enabled NAT behind the Teredo client handed out via UPnP ๐Ÿฆ‹ this field only has a valid value if the NAT the client is connected to is UPnP enabled. also, if the Teredo client sits behind a single NAT (not a bunch of nested NATs), this value matches the mapped address/port embedded in its Teredo IPv6 address ๐Ÿ‘‘

Symmetric NAT flag: a Boolean, set to TRUE if the Teredo client is behind a symmetric NAT ๐Ÿ’€

Peer Entry: this needs one new per-peer piece of state ๐Ÿงš

  • Symmetric Peer flag: a Boolean that's TRUE if the Teredo peer is behind a symmetric NAT ๐ŸŒธ

A Teredo client SHOULD also keep this state around across reboots ๐Ÿซถ

  • Persisted UPnP-Mapped Port: the mapped port the UPnP-enabled NAT gave the Teredo client ๐Ÿ“ this is the same as the UPnP-Mapped Port whenever both are non-zero. the default is all zero bytes.

5.3.2. Timers โฐ

no new timers needed, bestie. just the ones in [RFC4380] ๐ŸŒˆ

5.3.3. Initialization ๐Ÿš€

before the qualification procedure even starts, the Teredo client MUST first run the uninitialization procedure from Section 5.3.5.1, but only if the Persisted UPnP-Mapped Port is supported and non-zero ๐Ÿงน

then the Teredo client MUST invoke the AddPortMapping function, as described in Section 2.4.16 of [UPNPWANIP], with these parameters ๐Ÿ“

  • NewRemoteHost: "" (empty string)
  • NewExternalPort: Local Port value
  • NewProtocol: UDP
  • NewInternalPort: Local Port value
  • NewInternalClient: Local Address value
  • NewEnabled: TRUE
  • NewPortMappingDescription: "TEREDO"
  • NewLeaseDuration: 0

if AddPortMapping succeeds, that means the NAT has made a port mapping from its external port to the client's internal port โœจ the parameters are set up so any external host should be able to send packets to the client by sending them to the mapped address/port. if AddPortMapping fails, the Teredo client MUST carry on without this extension ๐Ÿ˜ญ otherwise, it MUST proceed like this ๐Ÿ‘‡

the Teredo client MUST set the UPnP-Mapped Port (and the Persisted UPnP-Mapped Port, if it's supported) to the Local Port value from AddPortMapping ๐Ÿ’– then it MUST call the GetExternalIPAddress function from Section 2.4.18 of [UPNPWANIP]. if GetExternalIPAddress fails, the Teredo client SHOULD run the uninitialization procedure from Section 5.3.5.1 and carry on without this extension ๐Ÿ™ˆ if GetExternalIPAddress succeeds, the Teredo client MUST proceed like this ๐Ÿ”ฅ

the Teredo client MUST set the UPnP-Mapped Address to the address that GetExternalIPAddress returned, and set the UPnP-Enabled NAT flag to TRUE ๐ŸŒŸ

during the qualification procedure (from Section 5.2.1 of [RFC4380]), when the Teredo client gets a response from the secondary Teredo server, the Teredo client MUST compare the mapped address/port it learned from that secondary server with the mapped address/port tied to the Teredo server ๐Ÿ‘€ if either the mapped address or the mapped port is different, the Symmetric NAT flag MUST be set to TRUE ๐Ÿ’…

after qualification, the mapped address/port learned from the Teredo server MUST be compared with the UPnP-Mapped Address/Port ๐Ÿ’œ if they match, the client is behind a single NAT, and the UPnP-Mapped Address/Port MUST be zeroed out ๐Ÿงผ

5.3.4. Message Processing ๐Ÿ’Œ

unless the following sections say otherwise, message processing follows Section 5.2.3 of [RFC4380] ๐Ÿฆ‹

5.3.4.1. Receiving a Direct Bubble ๐Ÿซง

except where it's noted below, direct bubbles get handled the way Section 5.2.4.4 says ๐Ÿ’โ€โ™€๏ธ

a Teredo client behind a UPnP-enabled NAT (port-restricted NAT as well as symmetric NAT) will receive every packet sent to the mapped address/port in its Teredo IPv6 address ๐ŸŽ€ so when it gets a direct bubble, the Teredo client MUST compare the mapped address/port the packet came from with the mapped address/port embedded in the Teredo IPv6 address in the IPv6 header's source address field ๐Ÿง if they're not the same, that tells the client the Teredo peer is behind a symmetric NAT, and the Teredo client MUST set the Symmetric Peer flag in its Peer Entry ๐Ÿ”ฅ

5.3.4.2. Sending a Direct Bubble ๐Ÿ“ค

the rules for sending a direct bubble live in Section 5.2.6 of [RFC4380] and Section 5.2.4.2 of this document ๐Ÿ“š these rules get a little extra refinement like this:

if the Teredo client sending the direct bubble meets ALL of these criteria ๐Ÿšจ

  • The Symmetric NAT flag is set to TRUE.
  • The UPnP-Enabled NAT flag is set to TRUE.
  • The UPnP-Mapped Address/Port are set to zero.
  • The peer's Symmetric Peer flag is set to TRUE.

then the Teredo client MUST send the direct bubble to the mapped address/port embedded in the peer's Teredo IPv6 address ๐Ÿช„

and here's why ๐Ÿค“ Symmetric-to-Symmetric and Port-Restricted-to-Symmetric NAT communication would've failed anyway. so the client takes a shot ๐ŸŽฏ in case the peer is also behind a UPnP-enabled NAT, like the client itself, it can try sending the direct bubble to the mapped address/port in the peer's Teredo IPv6 address. if it gets through, communication is established ๐ŸŽ‰

5.3.4.3. Sending a Data Packet ๐Ÿ“ฆ

the rules for sending a data packet are in Section 5.2.4 of [RFC4380] ๐Ÿ—‚๏ธ with this extra refinement:

if the Teredo client sending the data packet meets ALL of these criteria ๐Ÿšจ

  • The Symmetric NAT flag is set to TRUE.
  • The UPnP-Enabled NAT flag is set to TRUE.
  • The UPnP-Mapped Address/Port are set to zero.
  • The peer's Symmetric Peer flag is set to TRUE.

then the Teredo client MUST send the data packet to the mapped address/port embedded in the peer's Teredo IPv6 address ๐Ÿ’–

5.3.5. Shutdown ๐ŸŒ™

when Teredo client functionality is shutting down, uninitialization MUST be performed as Section 5.3.5.1 describes ๐Ÿ›‘

5.3.5.1. Uninitialization ๐Ÿงฝ

first, figure out the mapped port like this ๐Ÿ” if the Persisted UPnP-Mapped Port is supported, use it as the mapped port. otherwise, use the UPnP-Mapped Port.

if the mapped port is non-zero, the Teredo client MUST call the DeletePortMapping function from Section 2.4.17 of [UPNPWANIP] with these parameters ๐Ÿ—‘๏ธ

  • NewRemoteHost: "" (empty string)
  • NewExternalPort: the mapped port
  • NewProtocol: UDP

5.4. Port-Preserving Symmetric NAT Extension ๐ŸŒท

the Port-Preserving Symmetric NAT Extension is optional, but an implementation SHOULD support it ๐Ÿ’œ it depends on the Symmetric NAT Support Extension from Section 5.2, so any node that implements this extension MUST also implement the Symmetric NAT Support Extension ๐Ÿซถ

5.4.1. Abstract Data Model ๐Ÿง 

same disclaimer as before, bestie: this is a conceptual model. it explains the protocol, and you don't have to copy it, as long as your external behavior matches this document โœจ

this extension builds on the abstract data model in Section 5.2.1 and adds these fields:

Port-Preserving NAT flag: a Boolean, set to TRUE if the Teredo client is behind a port-preserving NAT ๐Ÿฆ„

Symmetric NAT flag: a Boolean, set to TRUE if the Teredo client is behind a symmetric NAT ๐Ÿ’€

Peer Entry: these fields need adding on a per-peer basis ๐Ÿงš

  • Random Port: the external port the Teredo client predicts its NAT assigned it for talking to the peer ๐Ÿ”ฎ default is zero.
  • Peer Random Port: the random port the peer is using to talk to this Teredo client ๐ŸŽ€ default is zero.
  • Direct Receive on Primary Port: a Boolean, set to TRUE if a packet came from the Teredo peer on the primary local port ๐Ÿ“ฌ default is FALSE.
  • Direct Receive on Random Port: a Boolean, set to TRUE if a packet came from the Teredo peer on the Random Port ๐Ÿ“ฎ default is FALSE.
  • Connection Refresh Count: how many direct bubbles have been sent to the peer since the last time data went to the peer ๐Ÿ”„
  • Last Data Packet Sent Timestamp: the timestamp of the last data packet sent to the peer โฑ๏ธ this one's different from the data-and-time-of-last-transmission field from Section 5.2 of [RFC4380], since that one also gets updated every time a direct bubble goes out ๐Ÿ™ƒ

5.4.2. Timers โฒ๏ธ

besides the ones in [RFC4380], the Port-Preserving Symmetric NAT Extension needs this extra timer ๐Ÿ•ฐ๏ธ

  • Peer Refresh Timer: refreshes peer connections through the random port when no data has been sent for a while ๐Ÿ’ซ

5.4.2.1. Peer Refresh Timer Expiry โŒ›

when the Peer Refresh Timer expires, the Teredo client MUST go through its list of peers ๐Ÿ“‹ for each peer it's talking to through the random port, the Teredo client MUST check the Last Data Packet Sent Timestamp to see if data went to that peer in the last 30 seconds ๐Ÿ‘€ it also MUST check the Connection Refresh Count to see if the count has hit the max allowed value of 20 ๐Ÿšซ if BOTH checks are FALSE, the Teredo client MUST send a direct bubble (as described in Section 5.4.4.3) to that peer and increment the Connection Refresh Count ๐Ÿซง the point of this direct bubble is to keep the port mappings on all the intermediate NATs alive while the app or user might be temporarily inactive ๐ŸŒˆ but if data has gone to the peer in the last 30 seconds, the Connection Refresh Count MUST be reset to zero ๐Ÿงน

the Peer Refresh Timer MUST then be rescheduled to expire in 30 seconds โฐ

5.4.3. Initialization ๐ŸŽ€

Okay so, on top of what [RFC4380] already says, the Port-Preserving NAT flag and Symmetric NAT flag MUST be set to FALSE when the Teredo client starts up. โœจ The Peer Refresh Timer MUST also be started and scheduled to expire in 30 seconds. โฐ

During the qualification procedure (as specified in Section 5.2.1 of [RFC4380]), when the Teredo client gets a response from the Teredo server address, it MUST compare the Port value in the origin indication (as specified in Section 5.1.1 of [RFC4380]) with the Local Port value. ๐Ÿ” If both values match, the client MUST set the Port-Preserving NAT flag to TRUE. ๐Ÿ’–

5.4.4. Message Processing ๐Ÿ’Œ

5.4.4.1. Sending a Data Packet ๐Ÿ“ค

On receiving a data packet that's headed to the Teredo peer (on top of the rules in Section 5.2.4 of [RFC4380]), the Teredo client MUST update the Last Data Packet Sent Timestamp when the packet is actually sent. ๐Ÿ•’

5.4.4.2. Sending an Indirect Bubble ๐Ÿซง

The rules for sending an indirect bubble are the ones in Section 5.2.4.1 of this document and Section 5.2.6 of [RFC4380]. ๐Ÿ“š On top of those, if the Port-Preserving NAT flag is TRUE, the Teredo client MUST do the following:

  • If the Symmetric NAT flag is set, the Teredo peer is not marked as "trusted" (as specified in Section 5.2 of [RFC4380]), and the Random Port is zero, the Teredo client MUST first pick a random port number to use, and then start listening on that port. ๐ŸŽฒ Since the NAT is port-preserving, the Teredo client can predict that the external port assigned will be equal to the random port chosen, so the Teredo client MUST store the random port chosen in the Random Port field of the Peer Entry. ๐Ÿง 
  • If the Random Port value is non-zero, the Teredo client MUST append a Random Port Trailer to the indirect bubble. ๐ŸŽ€

5.4.4.3. Sending a Direct Bubble ๐Ÿ’ซ

The rules for when direct bubbles get sent to a Teredo peer are in Section 5.2.6 of [RFC4380]. โœจ Section 5.2.4.2 adds rules for enabling communication for clients sitting behind a symmetric NAT. ๐Ÿ  On top of the rules in both of those sections, if the Port-Preserving NAT flag is TRUE, the following rules apply as well. ๐Ÿฆ‹

If the Symmetric NAT flag is set, and the Teredo peer is not marked as "trusted" (as specified in Section 5.2 of [RFC4380]), the Teredo client MUST send a direct bubble to the mapped address/port embedded in the Teredo IPv6 address of the Teredo peer. ๐ŸŽฏ If the peer Random Port field is non-zero, the Teredo client MUST send another direct bubble from its own random port, destined to the peer random port. ๐Ÿ” The IPv4 destination address MUST be the mapped address embedded in the Teredo IPv6 address. ๐ŸŒ Also, the Teredo client MUST include the Random Port Trailer (Section 4.5). ๐Ÿซถ

5.4.4.4. Receiving an Indirect Bubble ๐Ÿ“ฌ

The rules for processing an indirect bubble are in Section 5.2.4.3 of this document and Section 5.2.3 of [RFC4380]. ๐Ÿ“– On top of those, if the incoming indirect bubble has a Random Port Trailer, there's extra processing that MUST be done. ๐Ÿ‘€

If the Peer Random Port field of the Peer Entry is zero, the Teredo client MUST store the port from the Random Port Trailer in the Peer Random Port field of the Peer Entry. ๐Ÿ“

If the Peer Random Port field is non-zero, and either the Peer Random Port field and the new advertised port have the same value, or active data has been exchanged between the two Teredo clients in the last 30 seconds (that is, "time of last transmission" or "time of last reception", as specified in Section 5.2 of [RFC4380], is set to a time less than 30 seconds ago), then the new advertised port value MUST be ignored. ๐Ÿ™…โ€โ™€๏ธ

If the Peer Random Port field is non-zero and the new advertised port value is different from the Peer Random Port value, and it's been more than 30 seconds since the last exchange of data packets between the two Teredo clients (that is, "time of last transmission" and "time of last reception" are set to a time more than 30 seconds ago), the Teredo client SHOULD store the new advertised port value in the Peer Random Port field. ๐Ÿ”„ If the Port-Preserving NAT flag is TRUE, it then clears the Random Port field and stops listening on the old random port. ๐Ÿ›‘ This lets communication get re-established if either side changes the random port it's using. ๐Ÿฆ‹โœจ

5.4.4.5. Receiving a Direct Bubble ๐Ÿ’Œ

The rules for handling direct bubbles are in Section 5.2.4.4 of this document and Section 5.2.3 of [RFC4380]. ๐Ÿ“š The rules for whether to accept a direct bubble get extended like this when the Port-Preserving NAT flag is TRUE:

  • If the direct bubble is received on the primary port and the Teredo peer is not "trusted", the status field of the Teredo client MUST be changed to "trusted" and the Direct Receive on Primary Port flag MUST be set to TRUE. ๐Ÿฅฐ The mapped address/port the direct bubble came from MUST be recorded in the mapped address/port fields of the Teredo peer (as specified in Section 5.2 of [RFC4380]). ๐Ÿ“ The Teredo client MUST then set the Random Port field in the Peer Entry to zero and stop listening on the old random port. ๐Ÿงน
  • If the direct bubble is received on the primary port, the Teredo peer is "trusted", and the Direct Receive on Primary flag is set to TRUE, the Teredo client MUST compare the mapped address/port of the direct bubble with the mapped address/port of the Peer Entry. ๐Ÿ” If both mappings are the same, the direct bubble MUST be accepted. โœ… If the mappings are different, and it's been more than 30 seconds since the last packet exchange with the Teredo peer (that is, "time of last transmission" and "time of last reception", as defined in Section 5.2 of [RFC4380], are set to a time more than 30 seconds ago), then the mapping on the Teredo peer's NAT has changed and communication needs to be re-established. ๐Ÿ˜ค This MUST be done by changing the status of the peer to "not-trusted", setting the Direct Receive on Primary Port flag to FALSE, and sending an indirect bubble to the Teredo peer via its Teredo server. ๐Ÿ“ฎ
  • If the direct bubble is received on the primary port, the Teredo peer is "trusted", the Direct Receive on Primary Port flag is set to FALSE, and the Direct Receive on Random Port flag is set to TRUE, the mapped address/port the direct bubble is received from MUST be stored in the mapped address/port fields of the Peer Entry. ๐Ÿ—‚๏ธ The Direct Receive on Primary Port flag MUST be set to TRUE. โœ”๏ธ The Teredo client MUST then set the Random Port field in the Peer Entry to zero and stop listening on the old random port. ๐Ÿงผ Finally, the Direct Receive on Random Port flag MUST be set to FALSE. ๐ŸŒธ
  • If the direct bubble is received on the random port and the Teredo peer is not "trusted", the status field of the Teredo client MUST be changed to "trusted" and the Direct Receive on Random Port flag MUST be set to TRUE. ๐ŸŽ‰ The mapped address/port the direct bubble came from MUST be recorded in the mapped address/port fields of the Teredo Peer Entry, as specified in Section 5.2 of [RFC4380]. ๐Ÿ“
  • If the direct bubble is received on the random port, the Teredo peer is "trusted", and the Direct Receive on Primary Port flag is FALSE, the Teredo client MUST compare the mapped address/port in the direct bubble with the mapped address/port in the Peer Entry. ๐Ÿ” If the two mappings are the same, the direct bubble MUST be accepted. โœ… If the mappings are different, it implies that the NAT deleted the mapping and, when it reassigned one, picked a different external port. ๐Ÿคทโ€โ™€๏ธ In this case, the Teredo client SHOULD set the Random Port field to zero, stop listening on the old random port, and send an indirect bubble to the Teredo peer as specified in Section 5.4.4.2. ๐Ÿซง

Note that once the Direct Receive on Primary Port flag is TRUE, the client stops listening on the random port, so a direct bubble can't be received on the random port. ๐Ÿ™ˆ That's why this case is intentionally left out above. ๐Ÿ’…

5.5. Sequential Port-Symmetric NAT Extension ๐ŸŒˆ

The Sequential Port-Symmetric NAT Extension is optional; an implementation SHOULD support it. ๐Ÿงš This extension depends on the Symmetric NAT Support Extension (Section 5.2). ๐Ÿ”— Any node that implements this extension MUST also implement the Symmetric NAT Support Extension, as well as the Port-Preserving NAT Extension (Section 5.4). ๐Ÿ‘‘

5.5.1. Abstract Data Model ๐Ÿง 

This section describes a conceptual model of the data organization an implementation might keep to take part in this protocol. ๐Ÿ—บ๏ธ The organization is described to make it easier to explain how the protocol behaves. ๐Ÿ“– This document does not require implementations to follow this model, as long as their external behavior stays consistent with what's described in this document. ๐Ÿซถ

The Sequential Port-Symmetric NAT Extension extends the abstract data model in Section 5.4.1 by adding the following state. โœจ

Peer Entry: The following fields need to be added on a per-peer basis:

  • EchoTestNonce1: The value of the nonce sent as part of the authentication encapsulation (as specified in Section 5.1.1 of [RFC4380]) in the router solicitation packet sent to the Teredo server address as part of the Echo Test. ๐ŸŽ€
  • EchoTestNonce2: The value of the nonce sent as part of the authentication encapsulation in the router solicitation packet sent to the secondary Teredo server address as part of the Echo Test. ๐ŸŽ€
  • EchoTestLowerPort: The value of the external port mapping pulled out of the origin indication of the router advertisement received from the Teredo server address as part of the Echo Test. A value of 0 means no such router advertisement has been received. ๐Ÿ™ƒ
  • EchoTestUpperPort: The value of the external port mapping pulled out of the origin indication of the router advertisement received from the secondary Teredo server address as part of the Echo Test. A value of 0 means no such router advertisement has been received. ๐Ÿ™ƒ
  • EchoTestRetryCounter: The number of times an Echo Test has been attempted. ๐Ÿ”ข

5.5.2. Timers โฑ๏ธ

In addition to the timers specified in Section 5.4.2, the following additional timer is required per Peer Entry. ๐Ÿ’–

Echo Test Failover Timer: A one-shot timer that runs whenever an Echo Test is in progress. ๐Ÿƒโ€โ™€๏ธ

5.5.2.1. Peer Refresh Timer Expiry ๐ŸŒ™

The processing of the Peer Refresh Timer Expiry MUST be completed as specified in Section 5.4.2.1. ๐Ÿ“‹ On top of those rules, the Teredo client MUST set the EchoTestLowerPort, EchoTestUpperPort, and EchoTestRetryCounter to zero. ๐Ÿงน

5.5.2.2. Echo Test Failover Timer Expiry ๐Ÿ’ฅ

If the Echo Test Failover Timer expires, the Teredo client MUST do the following. โฐ

If the value of the EchoTestRetryCounter is two, then the Teredo client MUST send an indirect bubble as specified in Section 5.2.4.1. ๐Ÿซง

If the value of the EchoTestRetryCounter is one, then the Teredo client MUST start another Echo Test as specified in Section 5.5.4.1.1. ๐Ÿ”

5.5.3. Initialization ๐ŸŒธ

No behavior changes are required beyond what's specified in Section 5.4.3. ๐Ÿซถ

5.5.4. Message Processing โœจ

Okay so for message processing, everything works the same as Section 5.4.4 ๐Ÿซถ except for the bits the next sections spell out. Those are the exceptions, bestie ๐Ÿ’…

5.5.4.1. Handling a Request to Send an Indirect Bubble ๐Ÿฆ‹

Whenever [RFC4380] or another extension in this document says an indirect bubble is to be sent, these actions take over instead, but only if the Symmetric NAT flag is TRUE and the Port-Preserving NAT flag is FALSE ๐Ÿ‘€ Anything [RFC4380] or the other extensions say about how the indirect bubble gets built still counts ๐Ÿ’– It just happens at a later time, as laid out in Section 5.5.4.4.

If the Symmetric NAT flag is TRUE, the Port-Preserving NAT flag is FALSE, the Teredo peer is not marked as "trusted" (as specified in Section 5.2 of [RFC4380]), and the Random Port is zero, then the Teredo client MUST select a random port number to use, begin listening on that port, and start an Echo Test as described below โœจ

5.5.4.1.1. Starting an Echo Test ๐Ÿงš

To start an Echo Test, the Teredo client MUST send three packets from this port. It's giving very organized energy ๐ŸŽ€

  • First, a router solicitation (as specified in Section 5.2.1 of [RFC4380]) MUST be sent to the Teredo server address. That router solicitation MUST include an authentication encapsulation with a randomly generated Nonce field, as specified in Section 5.1.1 of [RFC4380]. The nonce inside that authentication encapsulation MUST then be stored in the EchoTestNonce1 field of the Peer Entry ๐ŸŒธ
  • Second, a direct bubble MUST be sent to the peer ๐Ÿ“
  • Third, a router solicitation MUST be sent to the secondary Teredo server address. It MUST include an authentication encapsulation with a randomly generated Nonce field, as specified in Section 5.1.1 of [RFC4380]. The nonce included in that authentication encapsulation MUST then be stored in the EchoTestNonce2 field of the Peer Entry ๐Ÿ’œ

After all that, the Teredo client MUST then increment the EchoTestRetryCounter and set the Echo Test Failover Timer to expire in a number of seconds equal to EchoTestRetryCounter โญ

5.5.4.2. Sending an Indirect Bubble ๐ŸŒˆ

The rules for sending an indirect bubble are as specified in Section 5.2.4.1 of this document and Section 5.2.6 of [RFC4380] ๐Ÿ“š On top of those rules, if the Symmetric NAT flag is TRUE, the Port-Preserving NAT flag is FALSE, and the Random Port value is non-zero, then the Teredo client MUST append a Random Port Trailer to the indirect bubble ๐ŸŽ€

5.5.4.3. Receiving a Direct Bubble ๐Ÿซง

The processing of the direct bubble MUST be completed as specified in Section 5.4.4.5, as if the Port-Preserving NAT flag were TRUE. Once that's done, if the Direct Bubble Received on Primary flag is TRUE and the Echo Test Failover Timer is running, then the Echo Test Failover Timer MUST be canceled and EchoTestLowerPort, EchoTestUpperPort, and EchoTestRetryCounter MUST be set to zero ๐Ÿงนโœจ

5.5.4.4. Receiving a Router Advertisement ๐Ÿ“ก

The rules for processing a router advertisement are as specified in Section 5.2.1 of [RFC4380]. On top of those, if the router advertisement contains an authentication encapsulation, the Teredo client MUST look for a Peer Entry whose EchoTestNonce1 or EchoTestNonce2 field matches the nonce in that authentication encapsulation ๐Ÿ” If a Peer Entry is found, the Teredo client MUST do the following ๐Ÿ’…

If the received nonce is equal to EchoTestNonce1 and EchoTestLowerPort is zero, then EchoTestLowerPort MUST be set to the external port mapping extracted from the origin indication of this router advertisement ๐ŸŒท

If the received nonce is equal to EchoTestNonce2 and EchoTestUpperPort is zero, then EchoTestUpperPort MUST be set to the external port mapping extracted from the origin indication of this router advertisement ๐ŸŒท

If EchoTestUpperPort and EchoTestLowerPort are now both non-zero, the Teredo client MUST then set the Random Port field of the Peer Entry to (EchoTestUpperPort + EchoTestUpperPort)/2, rounded down, and send an indirect bubble as specified in Section 5.5.4.2 ๐Ÿฅนโœจ

5.6. Hairpinning Extension ๐Ÿฆ‹

This extension is optional; an implementation SHOULD support it ๐Ÿซถ

5.6.1. Abstract Data Model ๐Ÿง 

This section describes a conceptual model of how an implementation might organize its data to take part in this protocol ๐Ÿ—‚๏ธ The model is only there to make it easier to explain how the protocol behaves. This document does not mandate that implementations adhere to this model, as long as their external behavior is consistent with what's described in this document ๐Ÿ’–

In addition to the state specified in Section 5.2 of [RFC4380], the following are also required:

UPnP Mapped Address/Port: The mapped address/port assigned via UPnP to the Teredo client by the UPnP-enabled NAT the Teredo client sits behind. This field has a valid value only if the NAT the Teredo client is connected to is UPnP enabled. Also, if the Teredo client is positioned behind a single NAT only (as opposed to a series of nested NATs), this value will be the same as the mapped address/port embedded in its Teredo IPv6 address ๐ŸŒธ

Peer Entry: Per-peer state is extended beyond what [RFC4380] describes by including the following:

  • Alternate Address/Port list: The list of alternate address/port pairs advertised by the peer ๐Ÿ“‹

5.6.2. Timers โฐ

No timers are necessary other than those in [RFC4380] ๐Ÿซง

5.6.3. Initialization ๐ŸŒฑ

Behavior is as specified in [RFC4380], with the following additions โœจ

Prior to beginning the qualification procedure, the Teredo client MUST invoke the AddPortMapping function (as specified in Section 2.4.16 of [UPNPWANIP]) with the parameters specified in Section 5.3.3. If it succeeds, that means the NAT has created a port mapping from the external port of the NAT to the internal port of the Teredo client node ๐ŸŽ‰ If the AddPortMapping function is successful, the Teredo client MUST store the mapping assigned by the NAT in its UPnP Mapped Address/Port state ๐Ÿ“ฆ

After the qualification procedure, the mapped address/port learned from the Teredo server MUST be compared to the UPnP Mapped Address/Port. If both are the same, the Teredo client is positioned behind a single NAT, and the UPnP Mapped Address/Port MUST be zeroed out ๐Ÿงน

5.6.4. Message Processing ๐Ÿ’ฌ

5.6.4.1. Sending an Indirect Bubble ๐Ÿ’Œ

The rules for when indirect bubbles are sent to a Teredo peer are as specified in Section 5.2.6 of [RFC4380]. If communication between a Teredo client and a Teredo peer has not been established, the Teredo client MUST include the Alternate Address Trailer in the indirect bubble ๐ŸŽ€ The Alternate Address Trailer MUST include the node's local address/port in the Alternate Address/Port list. If the UPnP Mapped Address/Port is non-zero, the Alternate Address Trailer MUST also include it in the list ๐ŸŒท

Hairpinning requires "direct IPv6 connectivity tests" (as specified in Section 5.2.9 of [RFC4380]) to succeed before it can accept packets from an IPv4 address and port not embedded in the Teredo IPv6 address ๐Ÿ™ˆ So, the indirect bubble MUST also include a Nonce Trailer ๐Ÿ”

5.6.4.2. Receiving an Indirect Bubble ๐Ÿ“ฅ

The rules for processing indirect bubbles are as specified in Section 5.2.3 of [RFC4380]. On top of those rules, when a Teredo client receives an indirect bubble with the Alternate Address Trailer, it SHOULD first verify that the Alternate Address Trailer is correctly formed (as specified in Section 4.3), and drop the bubble if it isn't ๐Ÿ”Ž Otherwise, it MUST set the Alternate Address/Port list in its Peer Entry to the list in the trailer ๐Ÿ“‹ The Teredo client, besides sending direct bubbles to the mapped address/port embedded in the Teredo IPv6 address (as specified in Section 5.2.6 of [RFC4380]), MUST also send a direct bubble to each mapped address/port advertised in the Alternate Address Trailer ๐Ÿš€

In each of the direct bubbles, the Teredo client MUST include a Nonce Trailer with the nonce value received in the indirect bubble ๐Ÿ”โœจ

5.6.4.3. Receiving a Direct Bubble ๐Ÿซถ

If the mapped address/port of the direct bubble matches the mapped address/port embedded in the source Teredo IPv6 address, the direct bubble MUST be accepted, as specified in Section 5.2.3 of [RFC4380] โœ…

If the mapped address/port does not match the embedded address/port, but the direct bubble contains a Nonce Trailer with a nonce that matches the Nonce Sent field of the Teredo peer, the direct bubble MUST be accepted ๐Ÿ™Œ

If neither of the above rules match, the direct bubble MUST be dropped ๐Ÿ—‘๏ธ

5.7. Server Load Reduction Extension ๐ŸŒ™

This extension is optional; an implementation SHOULD support it ๐Ÿ’œ

5.7.1. Abstract Data Model ๐Ÿง 

This section describes a conceptual model of how an implementation might organize its data to take part in this protocol. The described organization is there to help explain how the protocol behaves. This document does not mandate that implementations adhere to this model, as long as their external behavior is consistent with what's described in this document ๐Ÿซง

In addition to the state specified in Section 5.2 of [RFC4380], the following are also required.

Peer Entry: The following state needs to be added on a per-peer basis:

  • Count of Solicitations Transmitted: The number of Solicitation packets sent ๐Ÿ“ˆ

5.7.2. Timers โฒ๏ธ

Retransmission Timer: A timer used to retransmit Teredo Neighbor Solicitation packets ๐Ÿ”

When the retransmission timer expires, the Teredo client MUST retransmit a direct bubble with a Neighbor Discovery Option Trailer, and increment the Count of Solicitations Transmitted. If the count is less than three, it MUST then reset the timer to expire in two seconds ๐Ÿ•‘ Otherwise (if the count is now three), it MUST send an indirect bubble to the Teredo peer to re-establish connectivity, as if no communication between the Teredo client and the Teredo peer had been established ๐Ÿ˜ญ

5.7.3. Initialization ๐ŸŒผ

No initialization is necessary other than what's specified in [RFC4380] โœจ

5.7.4. Message Processing ๐Ÿ’ฌ

Except as specified below, processing is the same as specified in [RFC4380] ๐Ÿ’…

5.7.4.1. Sending a Data Packet ๐Ÿ“ค

Upon receiving a data packet to be transmitted to the Teredo peer, the Teredo client MUST determine whether data has been exchanged between the Teredo client and peer in either direction in the last 30 seconds (using the state as specified in Section 5.2 of [RFC4380]) ๐Ÿ‘€ If not, the Teredo client MUST send a direct bubble with a Neighbor Discovery Option Trailer having the DiscoveryType field set to TeredoDiscoverySolicitation. The Count of Solicitations Transmitted field MUST be set to 1, and the retransmission timer MUST be set to expire in two seconds โฐ๐ŸŽ€

5.7.4.2. Receiving a Direct Bubble ๐Ÿซง

The rules for processing direct bubbles are as specified in Section 5.2.3 of [RFC4380]. On top of those rules, upon receiving a direct bubble containing a Neighbor Discovery Option Trailer with the DiscoveryType field set to TeredoDiscoverySolicitation, the Teredo client MUST respond with a direct bubble with the Neighbor Discovery Option Trailer having the DiscoveryType field set to TeredoDiscoveryAdvertisement ๐Ÿฅฐ

6. Protocol Examples ๐ŸŒˆ

The following sections describe several operations as used in common scenarios, to show how the Teredo Extensions actually function ๐Ÿงš๐Ÿ’ซ

6.1. Symmetric NAT Support Extension ๐Ÿ’–

Okay bestie, this is the example for the Symmetric NAT Support Extension and it's giving main character energy ๐Ÿฆ‹ Let's walk through how it works.

Picture Figure 2 (Section 3.1). Teredo Client A is sitting behind a port-symmetric NAT and wants to talk to Teredo Client B, who is behind an address-restricted NAT ๐ŸŒธ

The qualification procedure, where the Teredo client figures out it's behind a symmetric NAT, is exactly the same as Section 5.2.1 of [RFC4380] ๐Ÿ’… Because of the Symmetric NAT Extension, Client A keeps configuring a Teredo IPv6 address even after finding out it's behind a symmetric NAT. Iconic โœจ

Next up, this packet exchange helps Teredo Client A (A) establish communication with Teredo Client B (B) ๐Ÿซถ

   Teredo           Client A's              Client B's           Teredo
   Client             Teredo                  Teredo             Client
      A        NAT    Server                  Server      NAT       B
      |         |        |                       |         |        |
      |         |        |  Direct Bubble to B   |         |        |
    1 |--------------------------------------------------->|        |
      |         |        |                       |         |        |
      |Indirect Bubble to B via B's Teredo Server|         |        |
    2 |----------------------------------------->|----------------->|
      |         |        |                       |         |        |
      |         |        |  Direct Bubble to A   |         |        |
      |         |<--------------------------------------------------| 3
      |         |        |                       |         |        |
      |         |        |Indirect Bubble to A via A's Teredo Server|
      |<-----------------|<-----------------------------------------| 4
      |         |        |                       |         |        |
      |         |        |  Direct Bubble to B   |         |        |
    5 |------------------------------------------------------------>|
      |         |        |                       |         |        |
      |Indirect Bubble to B via B's Teredo Server|         |        |
    6 |----------------------------------------->|----------------->|
      |         |        |                       |         |        |
      |         |        |  Direct Bubble to A   |         |        |
      |<------------------------------------------------------------| 7
      |         |        |                       |         |        |

Port-Symmetric NAT to Address-Restricted NAT Packet Exchange

  1. A sends a direct bubble (Packet 1) destined to the mapped address/port embedded in B's Teredo IPv6 address. The mapped port in the source field, assigned by Client A's NAT, is different from the mapped port embedded in A's Teredo IPv6 address. That's the port-symmetric NAT in front of A being extra ๐Ÿ’… The mapped address in the source field is the same as the mapped address embedded in A's Teredo IPv6 address.
  2. The direct bubble gets dropped by B's NAT because it hasn't seen any outgoing packet destined to A's mapped IPv4 address. Rude ๐Ÿ˜ญ
  3. A sends an indirect bubble (Packet 2) destined to B via Client B's Teredo server ๐Ÿงš
  4. B gets the indirect bubble and responds with a few packets. The first one B sends is a direct bubble (Packet 3) destined to the mapped address/port embedded in A's Teredo IPv6 address ๐Ÿ’œ
  5. A's NAT drops that direct bubble, because it hasn't seen any outgoing packet sourced from the mapped address/port embedded in A's Teredo IPv6 address and destined to the mapped address/port embedded in B's Teredo IPv6 address. Not me getting blocked again ๐Ÿ™ˆ
  6. B also sends an indirect bubble (Packet 4) destined to A via A's Teredo Server ๐ŸŒˆ
  7. A successfully receives that indirect bubble and responds with its own direct bubble (Packet 5). This direct bubble is exactly the same as the first direct bubble (Packet 1) that A sent ๐Ÿซถ
  8. This time, B's NAT accepts the direct bubble, because the NAT has seen an outgoing packet (Packet 3) sourced from the mapped address/port embedded in B's Teredo IPv6 address and destined to the mapped address/port embedded in A's Teredo IPv6 address. The plot twist: A's NAT is port-symmetric, so it changes only the mapped port while the mapped address stays the same. B's NAT is address-restricted, so it only cares about prior communication with the IPv4 address, not the specific port. ngl this is so clever ๐Ÿ”ฅ At this point, communication works in one direction (B to A, but not vice versa).
  9. Once B receives the direct bubble, it remembers the new mapped address/port from the source fields of that direct bubble, and uses those for future communication with A instead of the mapped address/port embedded in A's Teredo IPv6 address ๐ŸŽ€
  10. A times out and resends an indirect bubble (Packet 6). In response, B sends a direct bubble (Packet 7). That direct bubble is destined to the new learned mapped address/port, so A's NAT lets it through. Now communication works in the other direction (client A to B) ๐Ÿ‘‘โœจ

6.2. UPnP-Enabled Symmetric NAT Extension ๐ŸŽ€

This one shows the UPnP-Enabled Symmetric NAT Extension working alongside the Symmetric NAT Support Extension, so it's a double-layered glow-up ๐ŸŒธ

Say Teredo Client A is behind a UPnP-enabled port-symmetric NAT and wants to talk to Teredo Client B, who is also behind a UPnP-enabled port-symmetric NAT ๐Ÿฆ‹

Before both clients start their qualification procedure, they use UPnP to reserve port mappings on their respective NATs. The UPnP operations succeed for both clients, so they know they're behind UPnP-enabled NATs. After the qualification procedure, both clients have valid Teredo IPv6 addresses, because they both support the Symmetric NAT Support Extension. Also, after qualification, both clients compare their mapped address/port determined through UPnP with the mapped address/port determined through the qualification procedure. Since they're the same, the clients zero out their UPnP mapped address/port values and conclude that each is located behind a single UPnP-enabled NAT. Efficient and serving ๐Ÿ’…

The following packet exchange shows Teredo client A (A) establishing communication with Teredo client B (B) ๐Ÿซถ

   Teredo           Client A's              Client B's           Teredo
   Client             Teredo                  Teredo             Client
      A        NAT    Server                  Server      NAT       B
      |         |        |                       |         |        |
      |         |        |  Direct Bubble to B   |         |        |
    1 |------------------------------------------------------------>|
      |         |        |                       |         |        |
      |Indirect Bubble to B via B's Teredo Server|         |        |
    2 |----------------------------------------->|----------------->|
      |         |        |                       |         |        |
      |         |        |  Direct Bubble to A   |         |        |
      |<------------------------------------------------------------| 3
      |         |        |                       |         |        |

UPnP-enabled Symmetric NAT Packet Exchange

  1. A sends a direct bubble (Packet 1) to the mapped address/port embedded in B's Teredo IPv6 address. Because A's NAT is symmetric, the UDP source port field in the packet, assigned by A's NAT, is different from the mapped port embedded in A's Teredo IPv6 address. But the IPv4 source address of the packet is the same as the mapped address embedded in A's Teredo IPv6 address ๐Ÿงš
  2. The direct bubble is received by B, because it's destined for B's UPnP mapped address/port and so the NAT lets it through ๐ŸŒˆ At this point, B deduces that A is behind a symmetric NAT, because the mapped address/port the direct bubble came from is different from the mapped address/port embedded in A's Teredo IPv6 address. So B remembers that the peer is behind a symmetric NAT, and data packets will go to the mapped address/port embedded in A's Teredo IPv6 address, rather than the mapped address/port the direct bubble came from. Communication works in one direction (B to A, but not vice versa) ๐Ÿ’–
  3. A also sends an indirect bubble (Packet 2) destined to B via B's Teredo Server ๐Ÿ’œ
  4. The indirect bubble is received by B. B then responds with a direct bubble (Packet 3) destined to the mapped address/port embedded in A's Teredo IPv6 address, just like in step 2 ๐Ÿซถ
  5. Because A's NAT is also UPnP enabled, A receives that direct bubble. A also notices that B is behind a symmetric NAT, because the mapped address/port the packet came from is different from the mapped address/port embedded in B's Teredo IPv6 address. So A remembers that the peer is behind a symmetric NAT, and data packets will go to the mapped address/port embedded in B's Teredo IPv6 address, rather than the mapped address/port the direct bubble came from. Now communication works in the other direction (A to B) ๐Ÿ‘‘โœจ

6.3. Port-Preserving Symmetric NAT Extension โœจ

okay so this is the example where both clients are stuck behind a port-preserving symmetric NAT ๐Ÿฆ‹ and they still need to find each other. it's giving puzzle, bestie ๐Ÿงฉ

Let's say Teredo Client A (A) is behind a port-preserving symmetric NAT, and it wants to talk to Teredo Client B (B), who is also behind a port-preserving symmetric NAT ๐Ÿ’–

The packet exchange below shows how the two clients set up their configuration and get communication going ๐ŸŽ€

   Teredo           Client A's              Client B's           Teredo
   Client             Teredo                  Teredo             Client
      A        NAT    Server                  Server      NAT       B
      |         |        |                       |         |        |
      |         |        |  Direct Bubble to B   |         |        |
    1 |--------------------------------------------------->|        |
      |         |        |                       |         |        |
      |Indirect Bubble to B via B's Teredo Server|         |        |
    2 |----------------------------------------->|----------------->|
      |         |        |                       |         |        |
      |         |        |  Direct Bubble to A   |         |        |
      |         |<--------------------------------------------------| 3
      |         |        |                       |         |        |
      |         |        |  Direct Bubble to A   |         |        |
      |         |<--------------------------------------------------| 4
      |         |        |                       |         |        |
      |         |        |Indirect Bubble to A via A's Teredo Server|
      |<-----------------|<-----------------------------------------| 5
      |         |        |                       |         |        |
      |         |        |  Direct Bubble to B   |         |        |
    6 |--------------------------------------------------->|        |
      |         |        |                       |         |        |
      |         |        |  Direct Bubble to B   |         |        |
    7 |------------------------------------------------------------>|
      |         |        |                       |         |        |
      |Indirect Bubble to B via B's Teredo Server|         |        |
    8 |----------------------------------------->|----------------->|
      |         |        |                       |         |        |
      |         |        |  Direct Bubble to A   |         |        |
      |<------------------------------------------------------------| 9
      |         |        |                       |         |        |

               Port-Preserving Symmetric NAT Packet Exchange
  1. okay so first up, during the qualification procedure ๐Ÿ”, when the clients get a response from the Teredo server, they compare the Port value in the Origin indication with the Local Port value. if both values match, the clients set the Port-Preserving NAT flag to TRUE ๐Ÿ’…
  2. next, when the response comes back from the secondary Teredo server, the mapped address/port value in the Origin indication gets compared with the mapped address/port value learned from the response that came from the primary server. if the mappings are different, the Symmetric NAT flag gets set to TRUE ๐Ÿ”ฅ
  3. it's assumed that for both Clients A and B, the Port-Preserving NAT flag and the Symmetric NAT flag are both TRUE by the end of the qualification procedure โœจ
  4. before A sends anything to B, A checks whether it's behind a port-preserving NAT and a symmetric NAT (in this example, it is ๐Ÿ’€). A also checks whether the peer is "trusted", but it currently isn't ๐Ÿ™ˆ. Then A checks if the Random Port is non-zero. it's still zero, so A allocates a new random port, starts listening on it, and stores the value in the Random Port field ๐ŸŽ€
  5. A sends a direct bubble (Packet 1) from the primary port to the mapped address/port embedded in B's Teredo IPv6 address. this direct bubble has no Nonce Trailer and no Random Port Trailer attached ๐Ÿฆ‹
  6. the direct bubble gets dropped by B's NAT, because the NAT hasn't seen any outgoing packet going to A's mapped address ๐Ÿ˜ญ
  7. A sends an indirect bubble (Packet 2) to B through B's Teredo server ๐Ÿงš this one has two trailers: a Nonce Trailer with a random nonce, and a Random Port Trailer with the random port value from the Peer Entry. the nonce in the Nonce Trailer also gets stored in the Nonce Sent field of the Peer Entry ๐Ÿ’œ
  8. B receives that indirect bubble. B adds the Teredo peer to its peer list ๐Ÿ‘‘ then B saves the nonce from the Nonce Trailer in the Nonce Advertised field of the Peer Entry, and stores the port value from the Random Port Trailer in the Peer Random Port field of the Peer Entry ๐Ÿ“
  9. B responds with a bunch of packets ๐ŸŒˆ the first one is a direct bubble (Packet 3) sent from the primary port to the mapped address/port embedded in A's Teredo IPv6 address. it includes a Nonce Trailer carrying the nonce from the Nonce Advertised field of the Peer Entry ๐Ÿซถ
  10. the direct bubble gets dropped by A's NAT, since the NAT hasn't seen any outgoing packet sourced from the mapped address/port in A's Teredo IPv6 address and destined to the mapped address/port in B's Teredo IPv6 address ๐Ÿ˜ต
  11. B then checks whether it's behind a port-restricted NAT or a symmetric NAT, and whether the peer has already advertised a random port. here B is behind a port-preserving symmetric NAT and the peer has advertised a random port, so B needs to use a random port ๐Ÿ”ฅ it checks if its Random Port field is non-zero. it's still zero, so B allocates a new random port, starts listening on it, and stores it in the Random Port entry of the Peer Entry. then B sends a direct bubble (Packet 4) to the mapped address embedded in A's Teredo IPv6 address and the port stored in the Peer Random Port field of the Peer Entry. this direct bubble goes out from B's own random port ๐Ÿฆ‹
  12. the direct bubble above gets dropped by A's NAT, because the NAT hasn't seen any outgoing packet sourced from the mapped address embedded in A's Teredo IPv6 address and the random port A advertised ๐Ÿ’€
  13. B also sends an indirect bubble (Packet 5) to A through A's Teredo Server ๐Ÿงš this one includes a Nonce Trailer and a Random Port Trailer. the Nonce Trailer carries a new randomly generated nonce, which also gets stored in the Nonce Sent field of the Peer Entry. the Random Port Trailer carries the value from the Random Port field of the Peer Entry ๐Ÿ’–
  14. A successfully receives that indirect bubble โœจ A parses the trailers, stores the nonce from the Nonce Trailer in the Nonce Received field of the Peer Entry, and stores the port advertised in the Random Port Trailer in the Random Port field of the Peer Entry ๐ŸŽ€
  15. A responds to the indirect bubble with a few packets ๐ŸŒธ the first is a direct bubble (Packet 6) sent from the primary port to the mapped address/port embedded in B's Teredo IPv6 address ๐Ÿ’…
  16. that direct bubble gets dropped by B's NAT again, because the NAT hasn't seen an outgoing packet with the same 4-tuple as the incoming one ๐Ÿ˜ญ
  17. the next packet is also a direct bubble (Packet 7), and this one goes out from A's random port ๐Ÿฆ‹ it's destined to the mapped address embedded in B's Teredo IPv6 address and the Peer Random Port stored in the Peer Entry ๐Ÿงš
  18. okay this is the good part ๐Ÿฅน both NATs are port-preserving, and the random ports haven't been used for any other mapping, so B's NAT has already seen an outgoing packet (Packet 4) with the same address/port pairs. the direct bubble from Packet 7 gets received by B ๐ŸŽ‰ B stores the address/port it came from in the mapped address/port fields of the Peer Entry, changes the peer's status to "trusted", and sets the Direct Receive on Random Port field to TRUE. at this point, communication works in one direction (B to A, but not A to B) ๐Ÿ‘‘
  19. A still considers B to be "not-trusted", so it times out and retransmits an indirect bubble (Packet 8) ๐Ÿ” this packet has a new nonce in the Nonce Trailer, and it also has the value of the random port in the Random Port Trailer ๐Ÿซถ
  20. B receives that indirect bubble. processing it is similar to processing Packet 2 ๐Ÿ’… since B already received a direct bubble on its random port, it doesn't reply with a direct bubble from its primary port. instead, it replies with a direct bubble (Packet 9) sent from its random port, which is similar to Packet 4 mentioned above ๐ŸŒˆ
  21. A receives the direct bubble sent by B ๐ŸŽ€ A stores the mapped address/port that the direct bubble came from in the mapped address/port fields of the Peer Entry, changes B's status to "trusted", and sets the Direct Receive on Random Port field to TRUE. and just like that, communication is now possible in the other direction too (A to B) ๐Ÿฅณ๐Ÿ‘‘

6.4. Sequential Port-Symmetric NAT Extension โœจ

okay bestie, this is the example for the Sequential Port-Symmetric NAT Extension ๐Ÿฆ‹ Picture Teredo Client A (A) sitting behind a sequential port-symmetric NAT, and A is using the Sequential Port-Symmetric NAT Extension. A wants to talk to Teredo Client B (B), who is behind a port-restricted NAT that supports the Port-Preserving Port-Symmetric NAT Extension ๐ŸŒธ The packet exchange below shows how the two clients set up their configuration and then their communication ๐Ÿ’…

   Teredo                 A's      A's            B's
   Client               Primary  Secondary      Teredo          Client
      A        NAT      Server    Server        Server   NAT       B
      |         |          |        |              |      |        |
      | Direct Bubble to B |        |              |      |        |
    1 |-------------------------------------------------->|        |
      |         |          |        |              |      |        |
      |Router Solicitation |        |              |      |        |
    2 |------------------->|        |              |      |        |
      |         |          |        |              |      |        |
      |Router Advertisement|        |              |      |        |
      |<-------------------| 3      |              |      |        |
      |         |          |        |              |      |        |
    4 | Direct Bubble to B |        |              |      |        |
      |-------------------------------------------------->|        |
      |         |          |        |              |      |        |
      |  Router Solicitation        |              |      |        |
    5 |---------------------------->|              |      |        |
      |         |          |        |              |      |        |
      |  Router Advertisement       |              |      |        |
      |<----------------------------| 6            |      |        |
      |         |          |        |              |      |        |
      | Indirect Bubble to B via B's Teredo Server |      |        |
    7 |------------------------------------------->|-------------->|
      |         |          |        |              |      |        |
      |         |          |        |         Direct Bubble to A   |
      |         |<-------------------------------------------------| 8
      |         |          |        |              |      |        |
      |         |          |        |       Indirect Bubble to A   |
      |<-------------------|<--------------------------------------| 9
      |         |          |        |              |      |        |
      |         |          |        |         Direct Bubble to A   |
      |<-----------------------------------------------------------| 10
      |         |          |        |              |      |        |
      |   Direct Bubble to B        |              |      |        |
   11 |----------------------------------------------------------->|

               Sequential Port-Symmetric NAT Packet Exchange

Here's the play-by-play ๐ŸŽ€

  1. First up, the qualification procedure ๐Ÿ” When Client A gets a response from the Teredo Server, it compares the Port value in the Origin indication with the Local Port value. They're different, so A figures it isn't behind a port-preserving NAT, and assumes it's behind a sequential port-symmetric NAT. Lowkey detective energy ๐Ÿ•ต๏ธโ€โ™€๏ธ
  2. Next, A wants to talk to B, so A starts by sending a direct bubble (Packet 1) from its primary port. Why? Because A doesn't know B's NAT type, which could be a cone or address restricted NAT, or a UPnP-enabled NAT ๐Ÿ™ˆ Since A is behind a symmetric NAT, the external port its NAT uses is a brand new port. And this direct bubble gets dropped by B's NAT, because B is behind a port-restricted NAT ๐Ÿ’€
  3. A doesn't know whether B is behind a port-restricted NAT or some other kind of NAT, so A proactively opens a new random internal port, say, port 1100 โœจ
  4. Now A runs its Echo Test:
    • A. A sends a router solicitation (Packet 2) to its Teredo Server address from port 1100. The server answers with a router advertisement (Packet 3).
    • B. A sends a direct bubble (Packet 4) to the peer from port 1100, aimed at the port advertised in B's Teredo address, say, port 2100. B's port-restricted NAT drops this one too ๐Ÿ˜ญ
    • C. A sends a router solicitation (Packet 5) to its secondary Teredo server address from port 1100. The server responds with a router advertisement (Packet 6).
    • D. When A gets the router advertisements for Packet 2 and Packet 4, it learns that port 1100 maps to, say, port 1200 for Packet 2 and port 1202 for Packet 4 ๐Ÿงš
    • E. A then works out its predicted port for Packet 2 as the average of 1200 and 1202, rounded down, which is 1201 ๐Ÿ’–
  5. A sends out an indirect bubble (Packet 7). This one carries a random port trailer holding the predicted port, port 1201. And this indirect bubble does make it to B ๐Ÿซถ
  6. B responds to that indirect bubble by sending out these bubbles:
    • A. The first direct bubble (Packet 8) goes to the port mapping embedded in A's Teredo Address. (Fun fact, it's been observed that some NATs act symmetric for outgoing packets but cone for incoming ones. This direct bubble is likely to work if A's NAT behaves that way ๐ŸŒˆ) Here, though, A's NAT is a normal sequential port-symmetric NAT, so this packet gets dropped ๐Ÿฅ€
    • B. The second packet is an indirect bubble (Packet 9), sent to A without any trailers, since B is behind a port-restricted NAT ๐Ÿ“
    • C. The next one is a direct bubble (Packet 10) sent to port 1201. This one gets in to A, because A earlier sent an outgoing packet (Packet 4) with the same four tuple. And now communication works in one direction: A to B, but not vice versa ๐ŸŽ‰
  7. Finally, when A receives Packet 10, A sends a direct bubble (Packet 11) to B. This time it makes it through, because A previously sent an outgoing packet (Packet 10) with the same four tuple. So communication now works in the other direction too: B to A. Full two-way vibes at last ๐Ÿ‘‘๐Ÿ’œ

6.5. Hairpinning Extension

okay bestie ๐Ÿ’– this example is about the Hairpinning Extension and it is SO good ๐Ÿ˜ญ๐ŸŽ€

In Figure 3 (Section 3.5), Teredo Client A (A) and Teredo Client B (B) sit behind different immediate NATs in a two-layer NAT topology. The outermost NAT (NAT E) is shared by both A and B, but their immediate NATs are different: A is connected to NAT F and B is connected to NAT G. ๐Ÿงš Both NAT F and NAT G are UPnP-enabled. NAT E does not support hairpinning, which means it won't relay packets that come from the private address space and are headed for the NAT's own public address back to the private address of the NAT. ๐Ÿ™ˆ

Before starting the qualification procedure, both A and B use UPnP to reserve port mappings on their respective NATs. They check that the UPnP operation succeeds, and both clients get valid UPnP Mapped Address/Port values. โœจ

Next, both client A and client B run the qualification procedure to work out their mapped address/port values, as specified in Section 5.2.1 of [RFC4380]. ๐Ÿ’…

Then A and B compare their UPnP Mapped Address/Port values with the mapped address/port values they got from the qualification procedure. Because both A and B are part of a two-layer NAT topology, these values will be different. So both A and B keep holding on to their UPnP Mapped Address/Port. ๐ŸŒธ

Here's the packet exchange where client A sets up communication with client B:

Teredo             Teredo                      Client A's  Client B's
Client     NAT     Client        NAT      NAT    Teredo      Teredo
   A        F         B           G        E     Server      Server
   |        |         |           |        |        |           |
   |        | Direct Bubble to B  |        |        |           |
 1 |-------------------------------------->|        |           |
   |        |         |           |        |        |           |
   |       Indirect Bubble to B via B's Teredo Server           |
 2 |----------------------------------------------------------->|
   |        |         |<----------------------------------------|
   |        |         |           |        |        |           |
   |        |         | Direct Bubble to A |        |           |
 3 |        |         |------------------->|        |           |
   |        |         |           |        |        |           |
   |        |         |  Direct   |        |        |           |
   |        |         |Bubble to A|        |        |           |
 4 |        |         |---------->|        |        |           |
   |        |         |           |        |        |           |
   |        |         |  Direct   |        |        |           |
   |        |         |Bubble to A|        |        |           |
 5 |        |         |---------->|        |        |           |
   |<-----------------------------|        |        |           |
   |        |         |           |        |        |           |
   |        |         |    Indirect Bubble to A     |           |
 6 |        |         |---------------------------->|           |
   |<-----------------------------------------------|           |
   |        |         |           |        |        |           |
   |Direct Bubble to B|           |        |        |           |
 7 |----------------->|           |        |        |           |
   |        |         |           |        |        |           |

Hairpinning-Based Packet Exchange

  1. A sends a direct bubble (Packet 1) to the mapped address/port embedded in B's Teredo IPv6 address. ๐Ÿ“จ
  2. That direct bubble gets dropped by NAT E, because NAT E doesn't support Hairpinning. ๐Ÿ™ƒ
  3. A sends out an indirect bubble (Packet 2) to B via B's Teredo Server. In this indirect bubble, A includes an Alternate Address Trailer that has both the local address/port and the UPnP mapped address/port. ๐ŸŽ€
  4. B receives the indirect bubble. After parsing the Alternate Address Trailer, B has a total of three addresses to talk to: two from the Alternate Address Trailer and one from the mapped address/port embedded in A's Teredo IPv6 address. B then responds with these packets. The first one B sends is a direct bubble (Packet 3) headed for the mapped address/port embedded in A's Teredo IPv6 address. ๐Ÿ‘€
  5. That direct bubble gets dropped by NAT E, because NAT E doesn't support Hairpinning. ๐Ÿ’€
  6. Since the local address/port was the first mapping in the Alternate Address Trailer, the second direct bubble (Packet 4) that B sends goes to the local address/port. ๐Ÿง
  7. That direct bubble is dropped too, because A and B are behind different NATs, so they each have their own private address space. A's local address isn't reachable from B. ๐Ÿ˜ญ
  8. The next direct bubble (Packet 5) gets sent by B to A's UPnP mapped address/port, which is the second mapping in the Alternate Address Trailer that A sent. ๐Ÿฆ‹
  9. A receives that direct bubble, because A's UPnP-mapped address is reachable from B. A stores the source address the direct bubble came from in the mapped address/port fields of the Peer Entry, as defined in Section 5.2 of [RFC4380]. The mapped address status field (as specified in Section 5.2.3 of [RFC4380]) also changes to trusted. โœจ At this point, communication works in one direction (A to B), but not the other way around, because B hasn't marked A as trusted yet. ๐Ÿ“
  10. B also sends an indirect bubble (Packet 6) to A via A's Teredo server. B includes an Alternate Address Trailer in this indirect bubble too, and it has B's local address/port and UPnP mapped address/port. ๐Ÿ’Œ
  11. A receives that indirect bubble. After parsing the Alternate Address Trailer, A adds the two addresses from it to the Alternate Address List in the Peer Entry. Because the peer's mapping is trusted (point 9), A replies with just one direct bubble (Packet 7), sent to the mapped address/port stored in the Peer Entry. ๐Ÿซถ
  12. B receives that direct bubble. B records the mapped address/port the direct bubble came from in the mapped address/port field of its Peer Entry, and changes the status of that mapped address to trusted. And just like that, communication works in the other direction too (B to A). ๐Ÿ‘‘๐ŸŒˆ

6.6. Server Load Reduction Extension

this one's about the Server Load Reduction Extension, and it's giving efficiency ๐Ÿงš๐Ÿ’–

Say Teredo Client A (A) has already set up communication with Teredo Client B (B). Then, at some later point, no data packets have gone between the two clients for more than 30 seconds, and now A wants to send a data packet to B. So the communication has to be set up again. ๐Ÿซ 

The following packet exchange helps A re-establish communication with B:

Teredo           Client A's              Client B's           Teredo
Client             Teredo                  Teredo             Client
   A        NAT    Server                  Server      NAT       B
   |         |        |                       |         |        |
   |         |        |  Direct Bubble to B   |         |        |
 1 |------------------------------------------------------------>|
   |         |        |                       |         |        |
   |         |        |  Direct Bubble to A   |         |        |
   |<------------------------------------------------------------| 2
   |         |        |                       |         |        |

Server Load Reduction Packet Exchange

  1. A sends a direct bubble (Packet 1) with the Neighbor Discovery Option Trailer, and the DiscoveryType field is set to TeredoDiscoverySolicitation. ๐Ÿ“ฃ
  2. If the mapping on either of the NATs hasn't expired, B receives the direct bubble. B parses the Neighbor Discovery Option, and since the DiscoveryType was set to TeredoDiscoverySolicitation, B responds with a direct bubble (Packet 2). B's direct bubble also contains the Neighbor Discovery Option, and its DiscoveryType is set to TeredoDiscoveryAdvertisement. ๐ŸŒธ
  3. A receives that direct bubble, and at this point communication between the Teredo clients is re-established. ๐ŸŽ‰๐Ÿฆ‹

7. Security Considerations ๐Ÿ”

Security considerations are the same as those specified in Section 7 of [RFC4380]. Those apply in full here, so please don't skip them ๐Ÿ’€

Also, the Hairpinning Extension brings in the possibility of an amplification attack. If a malicious user could advertise a huge number of port mappings in the Alternate Address Trailer, that would result in a huge number of direct bubbles being sent back in response. ๐Ÿ˜ฑ Because of this, Section 4.3 explicitly limits the number of addresses a Teredo client will accept.

Be careful here, bestie. The nonce in the Nonce Trailer is used (as specified in Section 5.2.4.4) to stop spoofed bubbles from sending traffic to the wrong place. That's why it's so important that the nonce is random, so attackers can't predict its value. For more on randomness requirements, see [RFC4086]. ๐Ÿ”ฅ

8. Acknowledgements ๐Ÿซถ

Huge thanks to Gurpreet Virdi and Poorna Gaddehosur for their technical contributions to this document, and to the V6OPS WG and Jari Arkko for their helpful reviews. You all are literal main characters ๐Ÿ‘‘๐Ÿ’–


9. IANA Considerations ๐Ÿ“‹

IANA has created a new trailer Type registry. Requests for new trailer Type values are made through Specification Required [RFC5226]. The initial values are listed below. ๐ŸŒˆ

Trailer Type  Usage                              Reference
------------  ---------------------------------  ---------
   0x01       Nonce Trailer                      RFC 6081
   0x02       Random Port Trailer                RFC 6081
   0x03       Alternate Address Trailer          RFC 6081
   0x04       Neighbor Discovery Option Trailer  RFC 6081

10. References ๐Ÿ“š

10.1. Normative References ๐Ÿ“šโœจ

  • [RFC1918] Rekhter, Y., Moskowitz, R., Karrenberg, D., Groot, G., and E. Lear, "Address Allocation for Private Internets", BCP 5, RFC 1918, February 1996. ๐Ÿ 
  • [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997. ๐Ÿ”‘
  • [RFC2460] Deering, S. and R. Hinden, "Internet Protocol, Version 6 (IPv6) Specification", RFC 2460, December 1998. ๐ŸŒ
  • [RFC4380] Huitema, C., "Teredo: Tunneling IPv6 over UDP through Network Address Translations (NATs)", RFC 4380, February 2006. ๐Ÿฆ‹
  • [RFC4861] Narten, T., Nordmark, E., Simpson, W., and H. Soliman, "Neighbor Discovery for IP version 6 (IPv6)", RFC 4861, September 2007. ๐Ÿซถ
  • [RFC5226] Narten, T. and H. Alvestrand, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 5226, May 2008. ๐Ÿ“
  • [UPNPWANIP] UPnP Forum, "WANIPConnection:1", November 2001, <http://www.upnp.org/standardizeddcps/documents/UPnP_IGD_WANIPConnection%201.0.pdf>. ๐Ÿ”—

10.2. Informative References ๐ŸŒธ

  • [RFC4086] Eastlake, D., Schiller, J., and S. Crocker, "Randomness Requirements for Security", BCP 106, RFC 4086, June 2005. ๐ŸŽฒ
  • [RFC4443] Conta, A., Deering, S., and M. Gupta, "Internet Control Message Protocol (ICMPv6) for the Internet Protocol Version 6 (IPv6) Specification", RFC 4443, March 2006. ๐Ÿ’Œ
  • [RFC4787] Audet, F. and C. Jennings, "Network Address Translation (NAT) Behavioral Requirements for Unicast UDP", BCP 127, RFC 4787, January 2007. ๐Ÿงš

Author's Address ๐Ÿ’–

Dave Thaler
Microsoft Corporation
One Microsoft Way
Redmond, WA  98052
USA

Phone: +1 425 703 8835
EMail: dthaler@microsoft.com
๐Ÿ“ฆ where this page comes from