Skip to content

Commit

Permalink
GOAWAY is server-only; rearranging; Martin's feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
MikeBishop committed Jul 27, 2017
1 parent c08f315 commit 177db7c
Showing 1 changed file with 64 additions and 96 deletions.
160 changes: 64 additions & 96 deletions draft-ietf-quic-http.md
Expand Up @@ -588,81 +588,60 @@ The payload consists of:
### GOAWAY {#frame-goaway}

The GOAWAY frame (type=0x7) is used to initiate graceful shutdown of a
connection. GOAWAY allows an endpoint to stop accepting new streams while still
finishing processing of previously established streams. This enables
administrative actions, like server maintenance.

There is an inherent race condition between an endpoint starting new streams and
the remote sending a GOAWAY frame. To deal with this case, the GOAWAY contains
the stream identifier of the last peer-initiated stream that was or might be
processed on the sending endpoint in this connection. For instance, if the
server sends a GOAWAY frame, the identified stream is the highest-numbered
stream initiated by the client. This MAY be lower than the stream limit
identified by a QUIC MAX_STREAM_ID frame.

Once sent, the sender will refuse requests sent on streams initiated by the
receiver if the stream has an identifier higher than the included last stream
identifier. Receivers of a GOAWAY frame MUST NOT send new requests on the
connection, although a new connection can be established for new streams.

If the receiver of the GOAWAY has sent requests on streams with a higher stream
identifier than what is indicated in the GOAWAY frame, those streams are not or
will not be processed. The receiver of the GOAWAY frame can treat the requests
as though they had never been sent at all, thereby allowing those requests to be
retried later on a new connection. Servers SHOULD treat requests on streams
above this ID as stream errors of type HTTP_REQUEST_CANCELLED.

Endpoints SHOULD send a GOAWAY frame when the closing of a connection is known
in advance, even if the window is small, so that the remote peer can know
whether a stream has been partially processed or not. For example, if an HTTP
client sends a POST at the same time that a server closes a QUIC connection, the
client cannot know if the server started to process that POST request if the
server does not send a GOAWAY frame to indicate what streams it might have acted
on.

For unexpected closures caused by error conditions, transport-level mechanisms
SHOULD be used. However, a GOAWAY MAY still be sent to provide additional
detail to clients.

~~~~~~~~~~ drawing
+---------------------------------------------------------------+
| Last-Stream-ID (32) |
+---------------------------------------------------------------+
| [Error Code (32)] |
+---------------------------------------------------------------+
| [Additional Debug Data (*)] ...
+---------------------------------------------------------------+
~~~~~~~~~~
{: #fig-goaway title="GOAWAY frame payload"}

The GOAWAY frame does not define any flags.

The GOAWAY frame applies to the connection, not a specific stream. An endpoint
MUST treat a GOAWAY frame on a stream other than the control stream as a
connection error ({{errors}}) of type HTTP_WRONG_STREAM.

The last stream identifier in the GOAWAY frame contains the highest-numbered
stream identifier for which the sender of the GOAWAY frame might have taken some
action on or might yet take action on. All streams up to and including the
identified stream might have been processed in some way. The last stream
identifier can be set to 0 if no streams were processed.

> Note: In this context, "processed" means that some data from the stream was
> passed to some higher layer of software that might have taken some action as a
> result.

If a connection terminates without a GOAWAY frame, the last stream identifier is
effectively the highest possible stream identifier.

Reattempting requests on streams with lower- or equal-numbered identifiers is
not possible, with the exception of idempotent actions like HTTP GET, PUT, or
DELETE. Any protocol activity that used higher-numbered streams can be safely
retried using a new connection.

Activity on streams numbered lower or equal to the last stream identifier might
still complete successfully. The sender of a GOAWAY frame might gracefully shut
down a connection by sending a GOAWAY frame, maintaining the connection in an
"open" state until all in-progress streams complete.
connection by a server. GOAWAY allows a server to stop accepting new requests
while still finishing processing of previously received requests. This enables
administrative actions, like server maintenance. GOAWAY by itself does not
close a connection.

The GOAWAY frame does not define any flags, and the payload is a QUIC stream
identifier. The GOAWAY frame applies to the connection, not a specific stream.
An endpoint MUST treat a GOAWAY frame on a stream other than the control stream
as a connection error ({{errors}}) of type HTTP_WRONG_STREAM.

There is an inherent race condition between a client sending new requests and
the server sending a GOAWAY frame. To deal with this case, the GOAWAY contains
the stream identifier of the last client-initiated request that was or might be
processed in this connection. This MAY be lower than the stream limit
identified by a QUIC MAX_STREAM_ID frame, and MAY be zero if no requsets were
processed. Servers SHOULD NOT increase the MAX_STREAM_ID limit after sending a
GOAWAY frame.

Note:
: In this context, "processed" means that some data from the stream was
passed to some higher layer of software that might have taken some action as
a result.

Once sent, the server will refuse requests sent on streams with an identifier
higher than the included last stream identifier. Clients MUST NOT send new
requests on the connection after receiving GOAWAY, although requests might
already be in transit. A new connection can be established for new requests.

If the client has sent requests on streams with a higher stream identifier than
indicated in the GOAWAY frame, those requests were not and will not be
processed. The client can treat the requests as though they had never been sent
at all, thereby allowing those requests to be retried later on a new connection.
Servers SHOULD reset new streams above this ID with the error code
HTTP_REQUEST_CANCELLED. Servers MAY also reset streams below the indicated ID
with HTTP_REQUEST_CANCELLED if the associated requests were not processed.

Automatically retrying requests on streams with lower- or equal-numbered
identifiers is not possible, unless this is otherwise permitted (e.g. idempotent
actions like GET, PUT, or DELETE). These requests remain open until they are
completed successfully, reset, or the connection terminates.

Servers SHOULD send a GOAWAY frame when the closing of a connection is known
in advance, even if the advance notice is small, so that the remote peer can
know whether a stream has been partially processed or not. For example, if an
HTTP client sends a POST at the same time that a server closes a QUIC
connection, the client cannot know if the server started to process that POST
request if the server does not send a GOAWAY frame to indicate what streams it
might have acted on.

For unexpected closures caused by error conditions, a QUIC CONNECTION_CLOSE
frame MUST be used. However, a GOAWAY MAY be sent first to provide additional
detail to clients. If a connection terminates without a GOAWAY frame, the last
stream identifier is effectively the highest possible stream identifier (as
determined by QUIC's MAX_STREAM_ID).

An endpoint MAY send multiple GOAWAY frames if circumstances change. For
instance, an endpoint that sends GOAWAY without an error code during graceful
Expand All @@ -675,25 +654,13 @@ requests on another connection.
A client that is unable to retry requests loses all requests that are in flight
when the server closes the connection. A server that is attempting to
gracefully shut down a connection SHOULD send an initial GOAWAY frame with the
last stream identifier set to 2^32-1. This signals to the client that a
shutdown is imminent and that initiating further requests is prohibited. After
allowing time for any in-flight requests (at least one round-trip time), the
server MAY send another GOAWAY frame with an updated last stream identifier.
last stream identifier set to the current value of QUIC's MAX_STREAM_ID and
SHOULD NOT increase the MAX_STREAM_ID thereafter. This signals to the client
that a shutdown is imminent and that initiating further requests is prohibited.
After allowing time for any in-flight requests (at least one round-trip time),
the server MAY send another GOAWAY frame with an updated last stream identifier.
This ensures that a connection can be cleanly shut down without losing requests.

After sending a GOAWAY frame, the sender MUST reset any existing or subsequently
opened streams with an HTTP_REQUEST_CANCELLED error code.

The GOAWAY frame contains an optional 32-bit error code ({{http-error-codes}})
that contains the reason for closing the connection. If no error has been
encountered, this field MAY be omitted.

Endpoints MAY append opaque data to the payload of any GOAWAY frame. Additional
debug data is intended for diagnostic purposes only and carries no semantic
value. Debug information could contain security- or privacy-sensitive data.
Logged or otherwise persistently stored debug data MUST have adequate safeguards
to prevent unauthorized access.


# Error Handling {#errors}

Expand All @@ -707,9 +674,9 @@ the cause of a connection or stream error.

## HTTP-Defined QUIC Error Codes {#http-error-codes}

QUIC allocates error codes 0x0000-0x3FFF to application protocol definition.
The following error codes are defined by HTTP for use in QUIC RST_STREAM,
GOAWAY, and CONNECTION_CLOSE frames.
QUIC allocates error codes 0x0000-0x3FFF to application protocol definition. The
following error codes are defined by HTTP for use in QUIC RST_STREAM and
CONNECTION_CLOSE frames.

HTTP_PUSH_REFUSED (0x01):
: The server has attempted to push content which the client will not accept
Expand Down Expand Up @@ -848,7 +815,8 @@ PING (0x6):
: PING frames do not exist, since QUIC provides equivalent functionality.

GOAWAY (0x7):
: The error code in GOAWAY is optional. See {{frame-goaway}}.
: GOAWAY is sent only from server to client and does not contain an error code.
See {{frame-goaway}}.

WINDOW_UPDATE (0x8):
: WINDOW_UPDATE frames do not exist, since QUIC provides flow control.
Expand Down

0 comments on commit 177db7c

Please sign in to comment.