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

From: janaiyengar <[email-masked]>
Date: Wed, 07 Mar 2018 02:34:55 +0000 (UTC)

@janaiyengar pushed 1 commit.

0706fd9  comments

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/1012/files/5760cbea406c439c387b4c23021839437cc0f9e3..0706fd99f2f853e0b5c585d7cc19fdefd118e674

---

From: janaiyengar <[email-masked]>
Date: Tue, 06 Mar 2018 18:35:50 -0800

janaiyengar commented on this pull request.

Addressed comments, PTAL.

> @@ -1477,35 +1481,240 @@ connection if the integrity check fails with a PROTOCOL_VIOLATION error code.
 
 ## Connection Migration {#migration}

SGTM. done.

> @@ -1477,35 +1481,240 @@ connection if the integrity check fails with a PROTOCOL_VIOLATION error code.
 
 ## Connection Migration {#migration}
 
-QUIC connections are identified by their 64-bit Connection ID.  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 client migrating to a new
+network.  This section describes the protocol for migrating a connection to a
+new client address.
+
+Migrating a connection to a new server address is left for future work. If a
+client receives packets in the connection from a new server address, the client

That's a different sentence... I think it's still useful because if the packets don't belong to this connection, the rest of the sentence doesn't apply.

> -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 client migrating to a new
+network.  This section describes the protocol for migrating a connection to a
+new client address.
+
+Migrating a connection to a new server address is left for future work. If a
+client receives packets in the connection from a new server address, the client
+MAY discard these packets.
+
+
+### Path Validation {#migrate-validate}
+
+Path validation is used by a server to confirm the client's ownership of a
+new address and by a client to establish reachability to the server from a new
+local address.

Done (with some mods).

> +
+Migrating a connection to a new server address is left for future work. If a
+client receives packets in the connection from a new server address, the client
+MAY discard these packets.
+
+
+### Path Validation {#migrate-validate}
+
+Path validation is used by a server to confirm the client's ownership of a
+new address and by a client to establish reachability to the server from a new
+local address.
+
+To start path validation, an endpoint sends a PATH_CHALLENGE frame containing
+a payload that is hard to guess on the path to be validated.
+
+On receiving a PATH_CHALLENGE frame, the peer MUST immediately respond by

Ack delay does not apply, since it's not an ack that's being sent. Though this made me realize that I hadn't said anything about limiting the number of responses, so I've added some text (and moved some text around) limiting the rate at which responses are sent.

> +
+
+### Path Validation {#migrate-validate}
+
+Path validation is used by a server to confirm the client's ownership of a
+new address and by a client to establish reachability to the server from a new
+local address.
+
+To start path validation, an endpoint sends a PATH_CHALLENGE frame containing
+a payload that is hard to guess on the path to be validated.
+
+On receiving a PATH_CHALLENGE frame, the peer MUST immediately respond by
+echoing the data contained in the PATH_CHALLENGE frame in a PATH_RESPONSE frame.
+The PATH_RESPONSE MUST be sent on the same path: from the same local address on
+which the PATH_CHALLENGE was received, to the same remote address from which the
+PATH_CHALLENGE was received.

It was meant to establish reachability in both directions. I've written it down now.

> +
+On receiving a PATH_CHALLENGE frame, the peer MUST immediately respond by
+echoing the data contained in the PATH_CHALLENGE frame in a PATH_RESPONSE frame.
+The PATH_RESPONSE MUST be sent on the same path: from the same local address on
+which the PATH_CHALLENGE was received, to the same remote address from which the
+PATH_CHALLENGE was received.
+
+The new address is not considered valid until a PATH_RESPONSE frame containing
+the same payload is received, even if the packet containing the PATH_CHALLENGE
+frame is acknowledged.
+
+The PATH_RESPONSE frame MUST be received from the same remote address to which
+the corresponding PATH_CHALLENGE was sent. If a PATH_RESPONSE frame is received
+from a different remote address than the one to which the PATH_CHALLENGE was
+sent, path validation is considered to have failed, even if the data matches
+that sent in the PATH_CHALLENGE.

Perhaps this needs to be more explicitly stated, but bi-directional reachability is what is desired when doing connection migration to a new address. The test is incomplete if it only tests one direction. I've also added a sentence up above making this explicit.

> +
+The new address is not considered valid until a PATH_RESPONSE frame containing
+the same payload is received, even if the packet containing the PATH_CHALLENGE
+frame is acknowledged.
+
+The PATH_RESPONSE frame MUST be received from the same remote address to which
+the corresponding PATH_CHALLENGE was sent. If a PATH_RESPONSE frame is received
+from a different remote address than the one to which the PATH_CHALLENGE was
+sent, path validation is considered to have failed, even if the data matches
+that sent in the PATH_CHALLENGE.
+
+The PATH_RESPONSE frame MUST be received on the same local address from which
+the corresponding PATH_CHALLENGE was sent.  If a PATH_RESPONSE frame is received
+on a different local address than the one from which the PATH_CHALLENGE was
+sent, path validation is considered to have failed, even if the data matches
+that sent in the PATH_CHALLENGE.

done

> +sent, path validation is considered to have failed, even if the data matches
+that sent in the PATH_CHALLENGE.
+
+The PATH_RESPONSE frame MUST be received on the same local address from which
+the corresponding PATH_CHALLENGE was sent.  If a PATH_RESPONSE frame is received
+on a different local address than the one from which the PATH_CHALLENGE was
+sent, path validation is considered to have failed, even if the data matches
+that sent in the PATH_CHALLENGE.
+
+Thus, the endpoint considers the path to be valid when a PATH_RESPONSE frame is
+received on the same path with the same payload as the PATH_CHALLENGE frame.
+
+The endpoint MAY send additional PATH_CHALLENGE frames to handle packet loss,
+but is subject to the following limit to avoid excessive network load: an
+endpoint SHOULD NOT send more than one PATH_CHALLENGE frame in 200ms.  This
+limit is approximately equivalent to the network load due to a new connection,

Ok, removed the constant and used Ian's suggested text. There's a related issue of what a peer should do if it receives too many PATH_CHALLENGE frames back-to-back. It's not an attack, but the peer's behavior needs to be prescribed. I've added some text to allow limiting the rate at which PATH_RESPONSES are sent as well. I'm sure this can be made better, but I think what is there now is reasonable I think. I am happy to open an issue to make it better if anyone feels necessary.

> +
+The endpoint MAY send additional PATH_CHALLENGE frames to handle packet loss,
+but is subject to the following limit to avoid excessive network load: an
+endpoint SHOULD NOT send more than one PATH_CHALLENGE frame in 200ms.  This
+limit is approximately equivalent to the network load due to a new connection,
+and is based on the initial Handshake Timeout defined in {{QUIC-RECOVERY}}.
+
+The endpoint MUST use fresh random data in every PATH_CHALLENGE frame so that it
+can associate the peer's response with the causative PATH_CHALLENGE.
+
+The endpoint SHOULD abandon path validation after sending some number of
+PATH_CHALLENGE frames or after some time has passed.  When setting this timer,
+implementations are cautioned that the new path could have a longer roundtrip
+time than the original. The endpoint may receive packets containing other frames
+during this period, but a PATH_RESPONSE frame with appropriate data is required
+for the path validation to succeed.

Added text about keeping load the same as connection establishment, and added subsections (and restructured a bit).

> +possession of its address after a period of quiescence.
+
+An endpoint MAY bundle PATH_CHALLENGE and PATH_RESPONSE frames with other
+frames, as appropriate.  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.
+
+
+### Initiating Connection Migration {#initiating-migration}
+
+A client MAY initiate connection migration to a new local address in one of two
+ways.
+
+The client may immediately migrate the connection by sending all packets from
+the new local address.  Receiving acknowledgments for this data serves as proof
+of the server's reachability from the new address.  Note that since

It is fine for a client to move to a new address and start sending. Remember that this is the client migrating; the server isn't forcing it to migrate. A client doesn't *need* to validate if it is willing to send data right away -- the entire purpose of validation from a client's point of view is to make it possible for a client to check reachability to the server. I would argue that the p2p case is different. Surely a server can lie, but that's not the interesting case at all. The server isn't the one choosing to migrate, so the server lying is not an attack vector that makes any sense.

As discussed in the  editors' meeting, I've added some text to clarify.

> +with its own PATH_CHALLENGE.
+
+
+### Initiating Connection Migration {#initiating-migration}
+
+A client MAY initiate connection migration to a new local address in one of two
+ways.
+
+The client may immediately migrate the connection by sending all packets from
+the new local address.  Receiving acknowledgments for this data serves as proof
+of the server'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, a client
+MAY concurrently initiate path validation {{migrate-validate}} on the new path.
+
+Alternatively, the client may probe for server reachability from the new local

done

> +
+### Initiating Connection Migration {#initiating-migration}
+
+A client MAY initiate connection migration to a new local address in one of two
+ways.
+
+The client may immediately migrate the connection by sending all packets from
+the new local address.  Receiving acknowledgments for this data serves as proof
+of the server'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, a client
+MAY concurrently initiate path validation {{migrate-validate}} on the new path.
+
+Alternatively, the client may probe for server reachability from the new local
+address first using path validation {{migrate-validate}} and migrate the
+connection to the new address at a later time.  Failure of path validation

done

> +
+A client MAY initiate connection migration to a new local address in one of two
+ways.
+
+The client may immediately migrate the connection by sending all packets from
+the new local address.  Receiving acknowledgments for this data serves as proof
+of the server'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, a client
+MAY concurrently initiate path validation {{migrate-validate}} on the new path.
+
+Alternatively, the client may probe for server reachability from the new local
+address first using path validation {{migrate-validate}} and migrate the
+connection to the new address at a later time.  Failure of path validation
+simply means that the new local address is not usable for this connection and
+should not be fatal to the connection when alternative local addresses are

done

> +is not established. To establish return reachability on the new path, a client
+MAY concurrently initiate path validation {{migrate-validate}} on the new path.
+
+Alternatively, the client may probe for server reachability from the new local
+address first using path validation {{migrate-validate}} and migrate the
+connection to the new address at a later time.  Failure of path validation
+simply means that the new local address is not usable for this connection and
+should not be fatal to the connection when alternative local addresses are
+available.
+
+A client migrating to a new local address SHOULD use a new connection ID for
+packets sent from that address, see {{migration-linkability}} for further
+discussion.
+
+A client MUST NOT initiate connection migration before the handshake is
+finished and the client has 1-RTT keys.

Right -- this is specifying what a client MUST NOT do. A server should treat a change in 4-tuple as an error.

> +should not be fatal to the connection when alternative local addresses are
+available.
+
+A client migrating to a new local address SHOULD use a new connection ID for
+packets sent from that address, see {{migration-linkability}} for further
+discussion.
+
+A client MUST NOT initiate connection migration before the handshake is
+finished and the client has 1-RTT keys.
+
+
+### Responding to Connection Migration
+
+A server may receive a packet from a new client address at any time during the
+connection after the handshake is complete. If the packet is decryptable, the
+client may be either probing from a new address or migrating immediately, as

done

-Due to variations in path latency or packet reordering, packets from different
-source addresses might be reordered.  The packet with the highest packet number
-MUST be used to determine which path to use.  Endpoints also need to be prepared
-to receive packets from an older source address.
+A server MAY skip validation of a client address that it considers to be already
+valid.

Added clarifying text.

-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.
+Note that the server MAY send data to an unvalidated client address, but it MUST
+protect against potential attacks as described in {{address-spoofing}} and
+{{on-path-spoofing}}.
+
+If a non-probing packet is received from a new client address but with a packet
+number that is not the largest seen thus far, the server must process the packet

changed to "server processes"

-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.
+Note that the server MAY send data to an unvalidated client address, but it MUST
+protect against potential attacks as described in {{address-spoofing}} and
+{{on-path-spoofing}}.
+
+If a non-probing packet is received from a new client address but with a packet
+number that is not the largest seen thus far, the server must process the packet
+as usual, but it MUST ignore this client address under the assumption that it is
+not the client's most recent address.

added some text

-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.
+Note that the server MAY send data to an unvalidated client address, but it MUST
+protect against potential attacks as described in {{address-spoofing}} and
+{{on-path-spoofing}}.
+
+If a non-probing packet is received from a new client address but with a packet
+number that is not the largest seen thus far, the server must process the packet
+as usual, but it MUST ignore this client address under the assumption that it is
+not the client's most recent address.
+
+After verifying a new client address, the server SHOULD update any address
+validation tokens ({{address-validation}}) that it has issued to the client if
+those are no longer valid based on the changed address.

updated text

-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.
+It is possible that the client is spoofing its source address to cause the
+server to send excessive amounts of data to an unwilling host.  If the server
+sends significantly more data than the client, connection migration might be
+used to amplify the volume of data that an attacker can generate toward a
+victim.
+
+Thus, on receiving and decrypting a packet from an unvalidated address, the
+server MUST immediately validate the client's new address to confirm the
+client's possession of the new address.
+
+Until a client's address is deemed valid, the server MUST limit the rate at
+which it sends data to this address.  The server MUST NOT send more than 4 * MSS

added text and set the rate to min cwnd per rto.

> +
+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.
+
+To protect the connection from failing due to such a spurious migration, the
+server MUST revert to using the last validated client address when validation of
+a new client address fails. If the server has no state about the last validated
+client address, it MUST close the connection silently and discard any further
+packets received from the client for this connection.
+
+We note that receipt of packets with higher packet numbers from the legitimate

done

> +
+After successful validation of the client's new address, the server SHOULD reset
+its congestion controller and roundtrip time estimator prior to sending any
+further non-probing packets.
+
+An endpoint MUST NOT restore its send rate unless it is reasonably sure that the
+path is the same as the previous 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 rountrip times.  A receiver of packets on

the 'd' is redundant anyways, nobody pronounces it :-)
... though fixing english is not in charter, so fixing text

> @@ -1735,9 +1829,9 @@ state to draining, but it otherwise has no impact.
 An endpoint could receive packets from a new source address, indicating a
 connection migration ({{migration}}), while in the closing period. An endpoint
 in the closing state MUST strictly limit the number of packets it sends to this
-new address as though the address were not validated (see {{migrate-validate}}).
-A server in the closing state MAY instead choose to discard packets received
-from a new source address.
+new address since the address is not validated (see {{migrate-validate}}). A

done

-- 
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/1012#pullrequestreview-100268479

---

From: janaiyengar <[email-masked]>
Date: Wed, 07 Mar 2018 02:37:33 +0000 (UTC)

b75ea84  sigh. whitespace.

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/1012/files/0706fd99f2f853e0b5c585d7cc19fdefd118e674..b75ea84ae7cac2c324d697d38720af121245aafa

---

From: Mike Bishop <[email-masked]>
Date: Wed, 07 Mar 2018 08:22:54 -0800

MikeBishop commented on this pull request.

Worth noting that one-way reachability *might* be a thing once we get to multipath.  If client->server has two valid paths, but server->client only one, so be it.  But I don't object to saying path validation has to test both directions.

-- 
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/1012#discussion_r172899337

---

From: Mike Bishop <[email-masked]>
Date: Wed, 07 Mar 2018 08:42:27 -0800

MikeBishop approved this pull request.

Looking good.  Most of these are strictly wordsmithing.

...except that it isn't.  The title of the section is still "Connection Migration."

 

I'm in favor of Ian's change, because if packets don't map to a connection they'll be discarded anyway.  The extra words just sound awkward.  However, it's not technically incorrect, so this is purely wordsmithing.

+An endpoint MAY bundle PATH_CHALLENGE and PATH_RESPONSE frames with other
+frames, as appropriate.  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 payload that is hard to guess on the path to be validated.
+
+An endpoint MAY send additional PATH_CHALLENGE frames to handle packet loss,
+but is subject to the following limit to avoid excessive network load: an
+endpoint SHOULD NOT send a PATH_CHALLENGE more frequently than it would a client
+INITIAL, ensuring that connection migration is no more load on a new path than

Packet names are title-cased, not all-caps.  Also, I'd drop the colon lead-up.

`...but to avoid excessive network load, an endpoint SHOULD NOT... an Initial packet.  This ensures that....`

+An endpoint MAY send additional PATH_CHALLENGE frames to handle packet loss,
+but is subject to the following limit to avoid excessive network load: an
+endpoint SHOULD NOT send a PATH_CHALLENGE more frequently than it would a client
+INITIAL, ensuring that connection migration is no more load on a new path than
+establishing a new connection.
+
+The endpoint MUST use fresh random data in every PATH_CHALLENGE frame so that it
+can associate the peer's response with the causative PATH_CHALLENGE.
+
+
+#### Response
+
+On receiving a PATH_CHALLENGE frame, an endpoint MUST respond immediately by
+echoing the data contained in the PATH_CHALLENGE frame in a PATH_RESPONSE frame,
+with the following stipulation.  Since a PATH_CHALLENGE may be sent from a

"might be" - there's no permission involved here.

> +can associate the peer's response with the causative PATH_CHALLENGE.
+
+
+#### Response
+
+On receiving a PATH_CHALLENGE frame, an endpoint MUST respond immediately by
+echoing the data contained in the PATH_CHALLENGE frame in a PATH_RESPONSE frame,
+with the following stipulation.  Since a PATH_CHALLENGE may be sent from a
+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.
+
+Path validation tests both directions of a path.  To ensure reachability in both
+directions, 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.

and port, I presume?

+PATH_CHALLENGE frames or after some time has passed.  When setting this timer,
+implementations are cautioned that the new path could have a longer round-trip
+time than the original.  Again, to avoid excessive network load, an endpoint
+SHOULD NOT send more PATH_CHALLENGE frames than it would a client INITIAL,
+ensuring that connection migration is no more load on a new path than
+establishing a new connection.
+
+The endpoint may receive packets containing other frames during this period, but
+a PATH_RESPONSE frame with appropriate data is required for the path validation
+to succeed.
+
+
+### Initiating Connection Migration {#initiating-migration}
+
+A client MAY initiate connection migration to a new local address in one of two

This "MAY" seems superfluous, particularly since the first way also has a MAY.  I'd either lower-case it, "can", or "A client initiates...."  Also, I don't know that I'd frame these as two "ways" of migrating.  Ultimately, the client migrates by sending data from the new address/port.  A client MAY probe for reachability first, if it has the opportunity.

+### Handling Address Spoofing by an On-path Attacker {#on-path-spoofing}
+

How does this tie in to the closure/draining states described elsewhere?  Does the server enter draining?  Can it send Stateless Reset?

-- 
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/1012#pullrequestreview-101998058

---

From: janaiyengar <[email-masked]>
Date: Wed, 07 Mar 2018 20:02:52 +0000 (UTC)

5378c03  Mike's comments

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/1012/files/b75ea84ae7cac2c324d697d38720af121245aafa..5378c0305884dddb12aa4ee775fcee2b99adc6af

---

From: janaiyengar <[email-masked]>
Date: Wed, 07 Mar 2018 12:06:10 -0800

30025de  client connection migration

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/1012/files/5378c0305884dddb12aa4ee775fcee2b99adc6af..30025deb9f23233a56f2846fd39ba2a38c0e4f1e

---

From: janaiyengar <[email-masked]>
Date: Wed, 07 Mar 2018 12:03:19 -0800

Thanks, Mike. Addressed your comments, PTAL.

 

Ok, removed.

Fixed.

Ah, right. I'm always confused between may and might. This is a good way to think about it. Done.

+
+
+#### Response
+

an address is defined above as IP and/or port

Yes, that would be quite a different deal. You'd want to be very careful when thinking about reachability in the multipath case, but as you say, that's for a different day.

Good suggestions. I've made restructured a bit so that it flows as you suggest instead of "two ways".

Good q. I've changed it so that the server basically discards all connection state, leaving subsequent packets to be treated generically. That is, the server could send Stateless Resets in response. I think this is reasonable.

-- 
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/1012#pullrequestreview-102062168

---

From: erickinnear <[email-masked]>
Date: Wed, 07 Mar 2018 21:03:55 +0000 (UTC)

erickinnear commented on this pull request.

Latest changes look great! A few minor nits and other comments, but nothing major. 

+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 payload that is hard to guess on the path to be validated.
+
+An endpoint MAY send additional PATH_CHALLENGE frames to handle packet loss.  An
+endpoint SHOULD NOT send a PATH_CHALLENGE more frequently than it would an
+Initial packet, ensuring that connection migration is no more load on a new path
+than establishing a new connection.
+
+The endpoint MUST use fresh random data in every PATH_CHALLENGE frame so that it

Here we indicate that this should be random data, but above we just said "hard to guess" -- I know we took out the note about what's considered hard to guess, but perhaps we should still include a note in the above paragraph that it's random? 

I'd agree that requiring bi-directional reachability in this version is a good step, we can always remove that when defining true multipath. 

+sent, path validation is considered to have failed, even if the data matches
+that sent in the PATH_CHALLENGE.  Thus, the endpoint considers the path to be
+valid when a PATH_RESPONSE frame is received on the same path with the same
+payload as the PATH_CHALLENGE frame.
+
+
+#### Abandonment
+
+The endpoint SHOULD abandon path validation after sending some number of
+PATH_CHALLENGE frames or after some time has passed.  When setting this timer,
+implementations are cautioned that the new path could have a longer round-trip
+time than the original.  Again, to avoid excessive network load, an endpoint
+SHOULD NOT send more PATH_CHALLENGE frames than it would a client INITIAL,
+ensuring that connection migration is no more load on a new path than
+establishing a new connection.

Good to have this reminder so everything is in one place when implementing

> +payload as the PATH_CHALLENGE frame.
+
+
+#### Abandonment
+

Does this mean packets on the new path or on the old path? What are we trying to indicate here? 

+
+
+### Initiating Connection Migration {#initiating-migration}
+
+A client can migrate a connection to a new local address by sending all packets
+from the new local address.  Since the server's address is validated during
+connection establishment, receiving acknowledgments for this data serves as
+proof of the server'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, a client
+MAY concurrently initiate path validation {{migrate-validate}} on the new path.
+
+If it has the opportunity, a client MAY probe for server reachability from a
+new local address using path validation {{migrate-validate}} prior to migrating
+the connection to it.  Failure of path validation simply means that the new

nit: `to it` -> `to the new local 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 a packet from a new client address indicates that the client may be
+immediately migrating if
+
+* the packet is a "non-probing" packet. That is, it contains a frame other than
+PATH_CHALLENGE, PATH_RESPONSE, or PADDING; and
+
+* the packet carries a packet number that is the largest seen thus far.
+
+Upon receiving such a packet, the server MUST abandon any path validation it is
+performing with other addresses on the expectation that those validations are
+likely to fail.  Abandoning path validation primarily means ceasing subsequent
+transmissions of the PATH_CHALLENGE frame.  An endpoint MUST ignore any
+subsequently received PATH_RESPONSE frames from abandoned addresses.

This could mean the client ends up spending some additional time if it wants to re-establish reachability on the other addresses / maintain that ahead of time (like is best for performance). Probably okay, but worth considering. 

> +After verifying a new client address, the server SHOULD send new address
+validation tokens ({{address-validation}}) to the client if the current ones
+will not be adequate to validate the new client address.
+
+
+### Handling Address Spoofing by a Client {#address-spoofing}
+
+It is possible that the client is spoofing its source address to cause the
+server to send excessive amounts of data to an unwilling host.  If the server
+sends significantly more data than the client, connection migration might be
+used to amplify the volume of data that an attacker can generate toward a
+victim.
+
+Thus, on receiving and decrypting a packet from an unvalidated address, the
+server MUST immediately validate the client's new address to confirm the
+client's possession of the new address.

I worry that people may be confused by the perceived conflict between this and: 
```
A server MAY skip validation of a client address if it has been seen recently or
if the server has reasonable certainty that the new address is the result of a
NAT rebinding.
```

Can we resolve that somehow? 

Perhaps we could say above:
```
A server MAY consider validation to be complete for a client address that has been 
seen recently or if the server has reasonable certainty that the new address is the 
result of a NAT rebinding.
```
Or something to that effect (maybe `A server MAY deem a client address to be valid` to echo the next paragraph here). 

-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 a packet from a new client address indicates that the client may be
+immediately migrating if
+
+* the packet is a "non-probing" packet. That is, it contains a frame other than
+PATH_CHALLENGE, PATH_RESPONSE, or PADDING; and
+
+* the packet carries a packet number that is the largest seen thus far.
+
+Upon receiving such a packet, the server MUST abandon any path validation it is
+performing with other addresses on the expectation that those validations are
+likely to fail.  Abandoning path validation primarily means ceasing subsequent
+transmissions of the PATH_CHALLENGE frame.  An endpoint MUST ignore any
+subsequently received PATH_RESPONSE frames from abandoned addresses.

Ah, I see below that this allows us to avoid issues where someone tries to migrate us and we grab it back. Looks fine in that case. 

> +validation of the address of the spurious migration to be abandoned.
+
+
+### Loss Detection and Congestion Control
+
+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
+its congestion controller and round-trip time estimator prior to sending any
+further non-probing packets.
+
+An endpoint MUST NOT restore its send rate unless it is reasonably sure that the

Nit: `restore` -> `return to` ?

> @@ -1541,112 +1731,6 @@ number. "packet_number_secret" is derived from the TLS key exchange,
 as described in Section 5.6 of {{QUIC-TLS}}.

I agree with Christian, this seems fragile, but that's for another issue and discussion

-- 
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/1012#pullrequestreview-102083042

---

From: janaiyengar <[email-masked]>
Date: Thu, 08 Mar 2018 01:07:38 +0000 (UTC)

I've added "random" to the sentence above

-- 
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/1012#discussion_r173035812

---

From: janaiyengar <[email-masked]>
Date: Wed, 07 Mar 2018 18:17:46 -0800

b956ba8  eric's comments

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/1012/files/30025deb9f23233a56f2846fd39ba2a38c0e4f1e..b956ba8ca800f805e4e6d92ae4134da51df2e13b

---

From: janaiyengar <[email-masked]>
Date: Thu, 08 Mar 2018 02:18:05 +0000 (UTC)

Thanks, Eric, PTAL.

+
+
+#### Abandonment
+

I meant to say other packets might be received on the new path, but they are not adequate for validation. Fixed up sentence.

+
+

done

Hm. I don't think we need  a MUST ignore here. Changing to a MAY.

Good point. I've rephrased some things here and added an explicit sentence calling out that a server SHOULD NOT apply this limit when it is not validating the client address.

+
+

fixed up sentence too

-- 
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/1012#pullrequestreview-102157885

---

From: ianswett <[email-masked]>
Date: Wed, 07 Mar 2018 18:37:16 -0800

ianswett approved this pull request.

Small editorial nits, but the content LGTM.

I'm not seeing the change.

 ### Path Validation {#migrate-validate}
 
-Path validation is used by a server to confirm the client's ownership of a
-new address and by a client to establish reachability to the server from a new
-local address.
-
-To start path validation, an endpoint sends a PATH_CHALLENGE frame containing
-a payload that is hard to guess on the path to be validated.
+Path validation is used by the migrating endpoint to verify reachability of
+its peer from a new local address. Path validation is also used by the peer to

nit:s/its/the or a

+Additionally, the PATH_RESPONSE frame MUST be received on the same local address
+from which the corresponding PATH_CHALLENGE was sent.  If a PATH_RESPONSE frame
+is received on a different local address than the one from which the
+PATH_CHALLENGE was sent, path validation is considered to have failed, even if
+the data matches that sent in the PATH_CHALLENGE.  Thus, the endpoint considers
+the path to be valid when a PATH_RESPONSE frame is received on the same path
+with the same payload as the PATH_CHALLENGE frame.
+
+
+#### Abandonment
+
+An endpoint SHOULD abandon path validation after sending some number of
+PATH_CHALLENGE frames or after some time has passed.  When setting this timer,
+implementations are cautioned that the new path could have a longer round-trip
+time than the original.  Again, to avoid excessive network load, an endpoint

nit: "Again," is unnecessary.

> @@ -3599,7 +3629,7 @@ entire round trip.
 For smooth operation of the congestion controller, it is generally considered
 best to not let the sender go into quiescence if avoidable.  To avoid blocking a
 sender, and to reasonably account for the possibiity of loss, a receiver should
-send a MAX_DATA or MAX_STREAM_DATA frame at least two roundtrips before it
+send a MAX_DATA or MAX_STREAM_DATA frame at least two round trips before it

nit: Should it be round-trips as it is elsewhere?

-- 
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/1012#pullrequestreview-101958639

---

From: Mike Bishop <[email-masked]>
Date: Thu, 08 Mar 2018 20:44:22 +0000 (UTC)

Same issue with "Initial" as at ~1519.  BTW, double check that you actually need near-identical text both places?

-- 
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/1012#pullrequestreview-102451255

---

From: janaiyengar <[email-masked]>
Date: Thu, 08 Mar 2018 23:57:56 +0000 (UTC)

It's "round-trip time" or "round trip" elsewhere (I think, I'll make it consistent separately)

-- 
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/1012#discussion_r173330122

---

From: Christian Huitema <[email-masked]>
Date: Fri, 09 Mar 2018 00:39:49 +0000 (UTC)

I am looking at a stateless implementation of challenge/response. Not hard, but the 8 bytes challenge/response is a bit short.

-- 
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/1012#issuecomment-371674325

---

From: janaiyengar <[email-masked]>
Date: Fri, 09 Mar 2018 01:24:12 +0000 (UTC)

Good point -- I don't think I need it here. The earlier text is adequate. Removed.

-- 
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/1012#discussion_r173343209

---

From: janaiyengar <[email-masked]>
Date: Fri, 09 Mar 2018 01:24:40 +0000 (UTC)

be2afd3  comments

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/1012/files/b956ba8ca800f805e4e6d92ae4134da51df2e13b..be2afd3628dea564e019dc816d20e1aa0b4a17ca

---

From: janaiyengar <[email-masked]>
Date: Fri, 09 Mar 2018 01:27:36 +0000 (UTC)

@martinthomson : can you take a look? I'd like to merge tomorrow (Friday), but would like to confirm that you're fine with this.

-- 
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/1012#pullrequestreview-102520700

---

From: Martin Thomson <[email-masked]>
Date: Fri, 09 Mar 2018 01:35:30 +0000 (UTC)

martinthomson commented on this pull request.

> @@ -702,6 +702,10 @@ use it for all subsequent Handshake ({{packet-handshake}}) and 1-RTT
 Server's Version Negotiation ({{packet-version}}) and Retry ({{packet-retry}})
 packets MUST use connection ID selected by the client.
 
+Note that the connection ID may change during the connection via the use of
+NEW_CONNECTION_ID frames ({{frame-new-connection-id}}) and connection migration
+({{migration}}).
+

I'd prefer:

> The connection ID could change over the lifetime of a connection, especially in response to connection migration (cite).  NEW_CONNECTION_ID frames (cite) are used to provide new values.

-- 
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/1012#discussion_r173344400

---

From: janaiyengar <[email-masked]>
Date: Thu, 08 Mar 2018 17:41:55 -0800

done.

-- 
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/1012#discussion_r173345459

---

From: Martin Thomson <[email-masked]>
Date: Thu, 08 Mar 2018 19:46:34 -0800

martinthomson requested changes on this pull request.

This is still too one-sided for me sadly.  I would like this to say "endpoint" and "peer" everywhere it says "client" and "server", except for one paragraph that outlines why these mechanisms are only supported for client migration (i.e., because we don't want to deal with glare).

I also retain concerns about structure.  I find this structure hard to deal with because - though the requirements are all there and correct - they are distributed in a way that makes working through the process difficult.

I think that you want:

1. validation (this section is good)
2. migration
2.1. probing
2.2. migration at the initiating end
2.2.2. voluntary migration
2.2.1. involuntary migration
2.2. migration at the responding end
2.3. congestion/loss concerns

I'm happy to propose a remix of this text that follows that structure, but that will have to wait until next week.

+address and/or port), such as those caused by a client migrating to a new
+network.  This section describes the protocol for migrating a connection to a
+new client address.
+
+Migrating a connection to a new server address is left for future work. If a
+client receives packets from a new server address, the client MAY discard these
+packets.
+
+
+### Path Validation {#migrate-validate}
+
+Path validation is used 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 that
+address.  That is, that the packets received from the migrating endpoint do

"sent to *the migrated* address" perhaps?  The "that" is a bit hard to follow.

+
+with the following stipulation.  Since a PATH_CHALLENGE might be sent from a

"Path validation tests that packets can be both sent to and received from a peer."

The implication I got from reading this text was that a single validation process (CHALLENGE/RESPONSE) was sufficient for both peers to be satisfied that the path is good.  That's not the case: both endpoints need to do their own challenge.

+of the server's reachability from the new address.

Please avoid normative language then.

> +time than the original.
+
+Note that the endpoint might receive packets containing other frames on the new
+path, but a PATH_RESPONSE frame with appropriate data is required for path
+validation to succeed.
+
+

This paragraph has too many ideas for me.  Here's a breakdown:

You want to say that a client can initiate migration to a new address at any time.  You also should point out that the basic functions are potentially usable for server migration, but that is not supported due to not having a means of avoid glare.

The point about paths being validated (for both server and client) belongs elsewhere, likely in the introduction of the validation section.

Same again for the point about acknowledgments.  Receiving data (including acknowledgments) does not provide proof of return routeability (too low entropy).

So that leaves one idea in the first paragraph: who can do it, and what it is for.

Move the bit about concurrent path validation to a new paragraph.

---
Overall, I think that needs to be crisper than this and structuring this differently might help.

Give the migrating endpoint three sections:

* Speculative probing.  Why you might do it, and how you do it.  Maybe also what the reaction should be, so that this is self-contained.

* The voluntary migration an endpoint makes when it is aware of what it is doing.  This happens when an endpoint is aware that it is using a new address.  In this case, we should mandate path validation and a new congestion state (absent some heuristics about continuity).  Path validation might be concurrent with the change, particularly if the old path is gone, so this might appear to be involuntary at the server, but this is logically distinct.

* The involuntary migration (NAT rebinding) needs a section of its own too.

The peer of the migrating endpoint reacts differently, because the concurrent validation looks like involuntary migration to it.  Note - as you do - that it can tell between a speculative probe and actual migration by the presence of frames other than PATH_CHALLENGE in packets on the new path.  Then say that speculative probes don't trigger migration.  After that, the only thing you need to say is that send rate is limited until the path challenge is successful, and the congestion state is reset (absent continuity heuristics again - repetition of this theme suggests a section that you can point to and include some of the nuance) after it.

+To protect the connection from failing due to such a spurious migration, the
+server MUST revert to using the last validated client address when validation of
+a new client address fails.
+
+If the server has no state about the last validated client address, it MUST
+close the connection silently by discarding all connection state. This results
+in new packets on the connection being handled generically. For instance, an
+endpoint MAY send a stateless reset in response to any further incoming packets.
+
+Note that receipt of packets with higher packet numbers from the legitimate
+client 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

This section is good.  I worry a little that the pattern of acknowledgments triggered by this will leak information about what is going on, but I don't have a good solution for that here.

+It is possible that the client is spoofing its source address to cause the
+server to send excessive amounts of data to an unwilling host.  If the server
+sends significantly more data than the client, connection migration might be
+used to amplify the volume of data that an attacker can generate toward a
+victim.
+
+As described in {{migration-response}}, a server is required to validate the
+client's new address to confirm the client's possession of the new address.
+Until a client's address is deemed valid, the server MUST limit the rate at
+which it sends data to this address.  The server MUST NOT send more than a
+minimum congestion window's worth of data per estimated RTO period (as defined
+in {{QUIC-RECOVERY}}).  In the absence of this limit, the server risks being
+used for a denial of service attack against an unsuspecting victim.  Note that
+since the server will not have any round-trip time estimates to the new address,
+the RTO period is likely to be estimated based on the default initial RTT (see

"SHOULD be" not "likely to be"

I think that this text belongs in the section that deals with handling of migrations by the non-migrating peer.

+the data matches that sent in the PATH_CHALLENGE.  Thus, the endpoint considers
+the path to be valid when a PATH_RESPONSE frame is received on the same path
+with the same payload as the PATH_CHALLENGE frame.
+
+
+#### Abandonment
+
+An endpoint SHOULD abandon path validation after sending some number of
+PATH_CHALLENGE frames or after some time has passed.  When setting this timer,
+implementations are cautioned that the new path could have a longer round-trip
+time than the original.
+
+Note that the endpoint might receive packets containing other frames on the new
+path, but a PATH_RESPONSE frame with appropriate data is required for path
+validation to succeed.

You might also hint here that a path challenge might be abandoned for other reasons.  Primarily, this happens if a path challenge is initiated as a result of a path migration and another path migration occurs before it completes.

You also need to talk about failure.  If this timer pops, then the path is invalid and cannot be used further.

> @@ -1475,37 +1479,269 @@ failure.  If integrity protection is performed by QUIC, QUIC MUST abort the
 connection if the integrity check fails with a PROTOCOL_VIOLATION error code.

-## Connection Migration {#migration}
+## Client Connection Migration {#migration}
+
+QUIC allows connections to survive changes to endpoint addresses (that is, IP
+address and/or port), such as those caused by a client migrating to a new
+network.  This section describes the protocol for migrating a connection to a
+new client address.
+
+Migrating a connection to a new server address is left for future work. If a
+client receives packets from a new server address, the client MAY discard these
+packets.
+
+
+### Path Validation {#migrate-validate}

I think that you should promote this section one level and put it before connection migration generally.

+Path validation is used 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 that
+address.  That is, that the packets received from the migrating endpoint do
+not carry a spoofed source address.
+
+Path validation MAY be used at any time by either endpoint.  For instance, an
+endpoint might check that a peer is still in possession of its address after a
+period of quiescence.
+
+An endpoint MAY bundle PATH_CHALLENGE and PATH_RESPONSE frames with other
+frames, as appropriate.  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.
+

Please add a paragraph disclaiming any suitability for UDP NAT traversal.  Though these mechanisms might be effective for the creation of NAT bindings that support NAT traversal, the expectation is that one or other peer (typically the server) 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.

-- 
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/1012#pullrequestreview-102522179

---

From: janaiyengar <[email-masked]>
Date: Wed, 14 Mar 2018 00:04:32 +0000 (UTC)

441d6e9  martin comments

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/1012/files/be2afd3628dea564e019dc816d20e1aa0b4a17ca..441d6e9b555ef3265eaa33342ec51a94e8b9860a

---

From: janaiyengar <[email-masked]>
Date: Tue, 13 Mar 2018 17:04:53 -0700

done. I've redone the front matter in this section to flow better as a standalone.

replaced with "sent to its new address". I'm not sure if "its" is confusing; let me know if it is.

Added, PTAL.

+

done.

done.

removed.

done. I've simply moved this and the section below into the section above (Responding to Connection Migration).

+

Let's chat about this tomorrow.

-- 
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/1012#discussion_r174309998

---

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

Closed #1012 via #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/1012#event-1543971967