Subject: [quicwg/base-drafts] A more complete connection migration (#1249)

From: janaiyengar <[email-masked]>
Date: Mon, 26 Mar 2018 16:59:53 -0700

Closes #880 and #1012.

Moved #1012 here because unicorns are not nice.

This PR describes a more complete connection migration design, including:
- Allowing an endpoint to probe alternate paths without having to use them for data.
- Ensure that an endpoint validates peer ownership of a new address.

You can view, comment on, or merge this pull request online at:

  https://github.com/quicwg/base-drafts/pull/1249

-- Commit Summary --

  * Create new branch for migration PR (#1012) because unicorns are not nice.
  * remove overview. again.
  * sync
  * fix rebase

-- File Changes --

    M draft-ietf-quic-transport.md (414)

-- Patch Links --

https://github.com/quicwg/base-drafts/pull/1249.patch
https://github.com/quicwg/base-drafts/pull/1249.diff

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1249

---

From: Martin Thomson <[email-masked]>
Date: Mon, 26 Mar 2018 17:33:58 -0700

martinthomson approved this pull request.

Some nits, nothing major.  I'll probably land and fix if you don't get around to it.

>  ## Connection Migration {#migration}
 
-A QUIC connection can be identified using the Destination Connection ID included
-in packets.  QUIC's consistent connection ID allows connections to survive
-changes to the client's IP and/or port, such as those caused by client or server
-migrating to a new network.  Connection migration allows a client to retain any
-shared state with a connection when they move networks.  This includes state
-that can be hard to recover such as outstanding requests, which might otherwise
-be lost with no easy way to retry them.
+QUIC allows connections to survive changes to endpoint addresses (that is, IP
+address and/or port), such as those caused by a endpoint migrating to a new
+network.  This section describes the process by which an endpoint migrates to a
+new address.
+
+An endpoint MUST NOT initiate connection migration before the handshake is
+finished and the endpoint has 1-RTT keys.

Let's say that the handshake is complete instead.  Otherwise the server can migrate too soon.

> +
+An endpoint MAY probe for peer reachability from a new local address using path
+validation {{migrate-validate}} prior to migrating the connection to the new
+local address.  Failure of path validation simply means that the new path is not
+usable for this connection.  Failure to validate a path does not cause the
+connection to end unless there are no valid alternative paths available.
+
+An endpoint uses a new connection ID for probes sent from a new local address,
+see {{migration-linkability}} for further discussion.
+
+Receiving a PATH_CHALLENGE frame from a peer indicates that the peer is probing
+for reachability on a path. An endpoint sends a PATH_RESPONSE in response as per
+{{migrate-validate}}.
+
+PATH_CHALLENGE, PATH_RESPONSE, and PADDING frames are "probing" frames. If an
+endpoint has received packets containing only these frames from a given peer

"Until an endpoint receives packets containing other frames from a given peer address, it MUST NOT [...]"

-An endpoint MUST validate that its peer can receive packets at the new address
-before sending any significant quantity of data to that address, or it risks
-being used for denial of service.  See {{migrate-validate}} for details.
+However, the new path might not support the endpoint's current sending

s/However/When migrating/

-An endpoint MUST validate that its peer can receive packets at the new address
-before sending any significant quantity of data to that address, or it risks
-being used for denial of service.  See {{migrate-validate}} for details.
+However, the new path might not support the endpoint's current sending
+rate. Therefore, the endpoint resets its congestion controller, as described in
+{{migration-cc}}.
+
+Receiving acknowledgments for this data serves as proof of the peer's

s/this data/data sent on the new path/

> +validation tokens ({{address-validation}}) to the client.
+
+
+#### Handling Address Spoofing by a Peer {#address-spoofing}
+
+It is possible that a peer is spoofing its source address to cause an endpoint
+to send excessive amounts of data to an unwilling host.  If the endpoint sends
+significantly more data than the spoofing peer, connection migration might be
+used to amplify the volume of data that an attacker can generate toward a
+victim.
+
+As described in {{migration-response}}, an endpoint is required to validate a
+peer's new address to confirm the peer's possession of the new address.  Until a
+peer's address is deemed valid, an endpoint MUST limit the rate at which it
+sends data to this address.  The endpoint MUST NOT send more than a minimum
+congestion window's worth of data per estimated round-trip time (as defined in

mention kMinimumWindow 

> +to send excessive amounts of data to an unwilling host.  If the endpoint sends
+significantly more data than the spoofing peer, connection migration might be
+used to amplify the volume of data that an attacker can generate toward a
+victim.
+
+As described in {{migration-response}}, an endpoint is required to validate a
+peer's new address to confirm the peer's possession of the new address.  Until a
+peer's address is deemed valid, an endpoint MUST limit the rate at which it
+sends data to this address.  The endpoint MUST NOT send more than a minimum
+congestion window's worth of data per estimated round-trip time (as defined in
+{{QUIC-RECOVERY}}).  In the absence of this limit, an endpoint risks being used
+for a denial of service attack against an unsuspecting victim.  Note that since
+the endpoint will not have any round-trip time measurements to this address, the
+estimate SHOULD be the default initial value (see {{QUIC-RECOVERY}}).
+
+An endpoint SHOULD NOT apply this rate limit when the endpoint skips validation

Remove the "SHOULD NOT" (no interop requirement here).  Maybe:

If an endpoint skips validation of a peer address as described in {{migration-responses}}, it does not need to limit its sending rate.

> +congestion window's worth of data per estimated round-trip time (as defined in
+{{QUIC-RECOVERY}}).  In the absence of this limit, an endpoint risks being used
+for a denial of service attack against an unsuspecting victim.  Note that since
+the endpoint will not have any round-trip time measurements to this address, the
+estimate SHOULD be the default initial value (see {{QUIC-RECOVERY}}).
+
+An endpoint SHOULD NOT apply this rate limit when the endpoint skips validation
+of the peer's address, as described in {{migration-response}}.
+
+
+#### Handling Address Spoofing by an On-path Attacker {#on-path-spoofing}
+
+An on-path attacker could cause a spurious connection migration by capturing and
+forwarding a packet such that it arrives before the legitimate copy of that
+packet.  Such a packet will appear to be a legitimate connection migration and
+the legitimate copy will be dropped as a duplicate. After a spurious migration,

Two uses of "legitimate"

s/the legitimate copy will be dropped as a duplicate/the original packet appears to be a duplicate and will be dropped/

> +the endpoint will not have any round-trip time measurements to this address, the
+estimate SHOULD be the default initial value (see {{QUIC-RECOVERY}}).
+
+An endpoint SHOULD NOT apply this rate limit when the endpoint skips validation
+of the peer's address, as described in {{migration-response}}.
+
+
+#### Handling Address Spoofing by an On-path Attacker {#on-path-spoofing}
+
+An on-path attacker could cause a spurious connection migration by capturing and
+forwarding a packet such that it arrives before the legitimate copy of that
+packet.  Such a packet will appear to be a legitimate connection migration and
+the legitimate copy will be dropped as a duplicate. After a spurious migration,
+validation of the source address will fail because the entity at the source
+address does not have the necessary cryptographic keys to read or respond to the
+PATH_CHALLENGE frame that is sent to it, even if it wanted to.

drop from the comma

 ### Privacy Implications of Connection Migration {#migration-linkability}
 
+

Oops

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1249#pullrequestreview-107115409

---

From: janaiyengar <[email-masked]>
Date: Tue, 27 Mar 2018 06:33:21 +0000 (UTC)

@janaiyengar pushed 1 commit.

593a099  Martin's comments

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/1249/files/3285b54e085d8165c773420dbe5a39cf6bbb311a..593a099fc7ec71e75595fa9b838b9f653ed74978

---

From: janaiyengar <[email-masked]>
Date: Mon, 26 Mar 2018 23:33:55 -0700

janaiyengar commented on this pull request.

Thanks, Martin, changes made.

I don't follow. It does say "the handshake is finished". What change are you suggesting?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1249#pullrequestreview-107163599

---

From: janaiyengar <[email-masked]>
Date: Tue, 27 Mar 2018 06:34:59 +0000 (UTC)

7ef5a51  fix ref

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/1249/files/593a099fc7ec71e75595fa9b838b9f653ed74978..7ef5a5185650e520bba2d2b2c953ea3c581f8be2

---

From: Martin Thomson <[email-masked]>
Date: Tue, 27 Mar 2018 06:37:05 +0000 (UTC)

martinthomson commented on this pull request.

1-RTT keys != handshake finished, at least for a server.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1249#discussion_r177320746

---

From: Martin Thomson <[email-masked]>
Date: Tue, 27 Mar 2018 06:53:51 +0000 (UTC)

nevermind, misreading on my part

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1249#discussion_r177323530

---

From: ianswett <[email-masked]>
Date: Tue, 27 Mar 2018 07:24:55 -0700

ianswett commented on this pull request.

Thanks Jana, this is looking good.

> @@ -1451,29 +1454,276 @@ failure.  If integrity protection is performed by QUIC, QUIC MUST abort the
 connection if the integrity check fails with a PROTOCOL_VIOLATION error code.

+## Path Validation {#migrate-validate}
+
+Path validation is used by an endpoint to verify reachability of a peer over a

reachability implies only one direction(to me).  But I think you want to verify the full path works, correct?  Maybe bidirectional reachability or reachabilty in both directions?

> @@ -1451,29 +1454,276 @@ failure.  If integrity protection is performed by QUIC, QUIC MUST abort the
 connection if the integrity check fails with a PROTOCOL_VIOLATION error code.

+## Path Validation {#migrate-validate}
+
+Path validation is used by an endpoint to verify reachability of a peer over a
+specific path.  That is, it tests reachability between a specific local address
+and a specific peer address, where an address is the two-tuple of IP address and
+port.  Path validation tests that packets can be both sent to and received from
+a peer.
+
+Path validation is used during connection migration (see {{migration}}) by the
+migrating endpoint to verify reachability of a peer from a new local address.
+Path validation is also used by the peer to verify that the migrating endpoint
+is able to receive packets sent to the its new address.  That is, that the

"to the its new" -> "to its new" or "to the new"

> @@ -1451,29 +1454,276 @@ failure.  If integrity protection is performed by QUIC, QUIC MUST abort the
 connection if the integrity check fails with a PROTOCOL_VIOLATION error code.

+## Path Validation {#migrate-validate}
+
+Path validation is used by an endpoint to verify reachability of a peer over a
+specific path.  That is, it tests reachability between a specific local address
+and a specific peer address, where an address is the two-tuple of IP address and
+port.  Path validation tests that packets can be both sent to and received from
+a peer.
+
+Path validation is used during connection migration (see {{migration}}) by the
+migrating endpoint to verify reachability of a peer from a new local address.
+Path validation is also used by the peer to verify that the migrating endpoint
+is able to receive packets sent to the its new address.  That is, that the

Also, I'd say "This validation ensures the packets received from the migrating endpoint..."

> +mechanism described here might be effective for the creation of NAT bindings
+that support NAT traversal, the expectation is that one or other peer is able to
+receive packets without first having sent a packet on that path. Effective NAT
+traversal needs additional synchronization mechanisms that are not provided
+here.
+
+An endpoint MAY bundle PATH_CHALLENGE and PATH_RESPONSE frames that are used for
+path validation with other frames.  For instance, an endpoint may pad a packet
+carrying a PATH_CHALLENGE for PMTU discovery, or an endpoint may bundle a
+PATH_RESPONSE with its own PATH_CHALLENGE.
+
+
+### Initiation
+
+To initiate path validation, an endpoint sends a PATH_CHALLENGE frame containing
+a random payload that is hard to guess on the path to be validated.

nit: "that is hard to guess" seems redundant to random, so I would remove it.

+This document limits migration of connections to new client addresses.

It seems like this is the only paragraph that's client specific now.  Is there a reason to keep this paragraph now?

-An endpoint MUST validate that its peer can receive packets at the new address
-before sending any significant quantity of data to that address, or it risks
-being used for denial of service.  See {{migrate-validate}} for details.
+Receiving acknowledgments for data sent on the new path serves as proof of the
+peer's reachability from the new address.  Note that since acknowledgments may
+be received on any path, return reachability on the new path is not
+established. To establish return reachability on the new path, an endpoint MAY
+concurrently initiate path validation {{migrate-validate}} on the new path.
+
+
+### Responding to Connection Migration {#migration-response}
+
+Receiving a packet from a new peer address containing a non-probing frame

If a packet contains a PATH_CHALLENGE and a STREAM frame, then it contains a non-probing frame, but I don't think the intent is to immediately migrate.

How about "Receiving a packet from a new peer address that does not contain a PATH_CHALLENGE frame indicates the peer has migrated to that address."

+
+
+congestion window's worth of data per estimated round-trip time (kMinimumWindow,

Instead of the minimum window, we could use the limit in response to client initial of 3x, since I think we want migration to be governed by most of the rules of a new connection.

> +MAY send a stateless reset in response to any further incoming packets.
+
+Note that receipt of packets with higher packet numbers from the legitimate peer
+address will trigger another connection migration.  This will cause the
+validation of the address of the spurious migration to be abandoned.
+
+
+### Loss Detection and Congestion Control {#migration-cc}
+
+The capacity available on the new path might not be the same as the old path.
+Packets sent on the old path SHOULD NOT contribute to the state of the
+congestion control and RTT estimation on the new path. If it is using a single
+congestion controller and round-trip time estimator, the client SHOULD reset
+them prior to sending any non-probing packets from a new local address.
+
+After successful validation of the client's new address, the server SHOULD reset

This is almost identical to the end of the paragraph above it.

+An endpoint MUST NOT return to the send rate used for the previous path unless
+it is reasonably sure that the previous send rate is valid for the new path.
+For instance, a change in the client's port number is likely indicative of a
+rebinding in a middlebox and not a complete change in path.  This determination
+likely depends on heuristics, which could be imperfect; if the new path capacity
+is significantly reduced, ultimately this relies on the congestion controller
+responding to congestion signals and reducing send rates appropriately.
+
+There may be apparent reordering at the receiver when an endpoint sends data and
+probes from/to multiple addresses during the migration period, since the two
+resulting paths may have different round-trip times.  A receiver of packets on
+multiple paths will still send ACK frames covering all received packets.
+
+An endpoint MAY use a single congestion control context and a single loss
+recovery context, as described in {{QUIC-RECOVERY}}.  A sender MAY make

MAY -> SHOULD

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1249#pullrequestreview-107277106

---

From: Mike Bishop <[email-masked]>
Date: Tue, 27 Mar 2018 10:08:12 -0700

MikeBishop commented on this pull request.

There's more that's needed for a server migration, even though the mechanisms we have so far can be used in both.  I have a separate branch with the immediate-server-migration case, and we can follow on with "full" server migration if time permits.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1249#discussion_r177501278

---

From: Mike Bishop <[email-masked]>
Date: Tue, 27 Mar 2018 17:09:48 +0000 (UTC)

I think that's a substantive change to the design.  If you don't intend to migrate, you're not using that path for anything except probing.  If you're including a STREAM frame, then you are migrating, though you might also want to explicitly probe to be sure the migration is working.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1249#discussion_r177501727

---

From: ianswett <[email-masked]>
Date: Tue, 27 Mar 2018 10:19:14 -0700

Above the text says it's ok to bundle other frames with PATH_CHALLENGE, so I assumed STREAM frames were ok.  Is that not true?  Whatever we decide, this should be clear.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1249#discussion_r177504622

---

From: Mike Bishop <[email-masked]>
Date: Tue, 27 Mar 2018 17:32:45 +0000 (UTC)

MikeBishop approved this pull request.

Looking good.

> +spoofed address, an endpoint MAY limit the rate at which it sends PATH_RESPONSE
+frames and MAY silently discard PATH_CHALLENGE frames that would cause it to
+respond at a higher rate.
+
+To ensure that packets can be both sent to and received from the peer, the
+PATH_RESPONSE MUST be sent on the same path as the triggering PATH_CHALLENGE:
+from the same local address on which the PATH_CHALLENGE was received, to the
+same remote address from which the PATH_CHALLENGE was received.
+
+
+### Completion
+
+A new address is considered valid when a PATH_RESPONSE frame is received
+containing data that was sent in a previous PATH_CHALLENGE. Receipt of an
+acknowledgment for a packet containing a PATH_CHALLENGE frame is not adequate
+validation, since the acknowledgment can be spoofed by a malicious client.

"client" => "peer"

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1249#pullrequestreview-107389932

---

From: janaiyengar <[email-masked]>
Date: Tue, 27 Mar 2018 11:47:40 -0700

93d9e77  comments

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/1249/files/7ef5a5185650e520bba2d2b2c953ea3c581f8be2..93d9e77fd1d44900b4a131ca31a6c96a33955cd2

---

From: janaiyengar <[email-masked]>
Date: Tue, 27 Mar 2018 11:48:12 -0700

Comments done.

The last sentence in this para is supposed to capture that. It's not bidirectional in the sense that the peer has to do its own validation... so saying "both directions" can be a bit misleading

What Mike said.

It's ok to bundle other frames, as the server might, when it's verifying client ownership of the new address. But if a client sends anything but probing frames to the server, the server considers this as a migration, not a probe.

+
+

I'd rather leave this at min cwnd for now, and we can fix this later if necessary.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1249#pullrequestreview-107412588

---

From: janaiyengar <[email-masked]>
Date: Tue, 27 Mar 2018 18:50:36 +0000 (UTC)

I am merging this PR -- it's been doing the rounds for way too long now. There's agreement on the key mechanism, and if there are clarifications that need to be done, I'm happy to do those in a follow-up PR.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1249#pullrequestreview-107421451

---

From: janaiyengar <[email-masked]>
Date: Tue, 27 Mar 2018 18:50:56 +0000 (UTC)

Merged #1249.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1249#event-1543971953