RE: Comments on Section 6.1 (Persistent Connections) of HTTPbis Part 1, version 17

Hello Willy,

In response to our remark:
>> These points concentrate on the opening phase of TCP causing
>>delay, because of the 3 way handshake, but equally important is
>>the graceful closing phase, which requires handshakes in both
>>directions (FIN followed by ACK for each side), and the holding
>>of the TIMEWAIT state, causing further delay. Because it is
>>equally important to the closing phase, we feel it is useful to
>>include this point in the list of advantages.

You wrote:
>In fact it depends who closes first and how the close is performed. If the
>server closes first, you have the usual 3-way handshake and there is no
>delay imposed by the TIME_WAIT state because while the socket remains in
>this state on the server, it can immediately be reopened when the client
>provides a new SYN above the end of the last window.

This last sentence does not correspond to TCP in RFC793.
1. When closing you have two relatively independent two way handshakes (FIN then ACK) as described above, rather than a 3-way handshake.
2. On page 69 of RFC 793 it describes the conditions under which a segment is acceptable in the TIME-WAIT state. It is not acceptable if it is outside the window, which is the case if the sequence number of the new SYN is "above the end of the last window". In this case the RFC states:

        If an incoming segment is not acceptable, an acknowledgment
        should be sent in reply (unless the RST bit is set, if so drop
        the segment and return):

          <SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK>

        After sending the acknowledgment, drop the unacceptable segment
        and return.

This is further backed up in the case of SYNs on the bottom of page 71. Thus on receipt of a SYN in this case, the server would return an ACK and remain in the TIME-WAIT state, until the 2MSL timer expires. There is also a clarification of this situation in RFC 1122 on page 88.

            When a connection is closed actively, it MUST linger in
            TIME-WAIT state for a time 2xMSL (Maximum Segment Lifetime).
            However, it MAY accept a new SYN from the remote TCP to
            reopen the connection directly from TIME-WAIT state, if it:

            (1)  assigns its initial sequence number for the new
                 connection to be larger than the largest sequence
                 number it used on the previous connection incarnation,
                 and

            (2)  returns to TIME-WAIT state if the SYN turns out to be
                 an old duplicate.

Note the mandatory requirement (MUST) to stay in the TIME-WAIT state for 2MSL. The additional text allows (MAY) a SYN to be received (and not dropped) in TIME-WAIT, with presumably a transition to SYN_RCVD (and sending of the SYNACK) after the 2MSL timer expires (to obey the mandatory requirement). Thus TCP does not have to return to LISTEN, it can transition directly from TIME-WAIT to SYN_RCVD. Ignoring the 2MSL requirement is done at your peril, as this could lead to old duplicate segments being accepted instead of the new ones (not good for financial transactions or safety critical applications).

>If the client closes first using the 3-way handshake, then what you describe
>happens and in practice the client is stuck. For this reason, when clients
>absolutely needs to close, they usually close with an RST which saves them
>from the TIME_WAIT delay and at the same time saves bandwidth since only one
>packet is sent.

The use of RST to close is not mentioned in Part 1 as far as I am aware. On the contrary, one gets the impression in section 6.1.4 Practical Considerations, that the graceful close should be used, at least for timeouts:

   When a client or server wishes to time-out it SHOULD issue a graceful
   close on the transport connection.

This seems to relate to active ticket #176 where the use of graceful close (half-close) is also suggested, to avoid loss of responses.

>> Proposed Replacement text:
>> Third point:
>> "Network congestion is reduced by eliminating the packets associated with TCP's three way handshake and graceful close procedures, and by allowing TCP sufficient time to determine the congestion state of the network."
>> Fourth Point:
>> "Latency on subsequent requests is reduced since there is no time spent in the double handshakes required for gracefully closing TCP connections and holding the TIMEWAIT state, and in TCP's connection opening handshake, when reopening the connection."

>I think the 4th point can be left intact without the TIME_WAIT add-on.

See discussion above regarding the mandatory requirement of holding TIME-WAIT in RFCs 793 and 1122. With respect to IETF standards, I think the case is made. That implementers are ignoring the TIME-WAIT state to improve performance at the expense of safety makes me uncomfortable.

This is long enough for this message. I shall address the other points in my next message.

Jonathan

-----Original Message-----
From: Willy Tarreau [mailto:w@1wt.eu]
Sent: Tuesday, 20 December 2011 5:56 PM
To: Jonathan Billington
Cc: ietf-http-wg@w3.org; Sonya Arnold
Subject: Re: Comments on Section 6.1 (Persistent Connections) of HTTPbis Part 1, version 17

Hello,

On Tue, Dec 20, 2011 at 12:52:01PM +1030, Jonathan Billington wrote:
> 1.  Section 6.1.1 Purpose
> Change Type: Editorial clarification
> Rationale: This section includes a list of advantages of using persistent HTTP connections. The third and fourth points state:
> "Network congestion is reduced by reducing the number of packets caused by TCP opens, and by allowing TCP sufficient time to determine the congestion state of the network."
> "Latency on subsequent requests is reduced since there is no time spent in TCP's connection opening handshake."
>
> These points concentrate on the opening phase of TCP causing delay, because of the 3 way handshake, but equally important is the graceful closing phase, which requires handshakes in both directions (FIN followed by ACK for each side), and the holding of the TIMEWAIT state, causing further delay. Because it is equally important to the closing phase, we feel it is useful to include this point in the list of advantages.

In fact it depends who closes first and how the close is performed. If the
server closes first, you have the usual 3-way handshake and there is no
delay imposed by the TIME_WAIT state because while the socket remains in
this state on the server, it can immediately be reopened when the client
provides a new SYN above the end of the last window.

If the client closes first using the 3-way handshake, then what you describe
happens and in practice the client is stuck. For this reason, when clients
absolutely needs to close, they usually close with an RST which saves them
from the TIME_WAIT delay and at the same time saves bandwidth since only one
packet is sent.

> Proposed Replacement text:
> Third point:
> "Network congestion is reduced by eliminating the packets associated with TCP's three way handshake and graceful close procedures, and by allowing TCP sufficient time to determine the congestion state of the network."
> Fourth Point:
> "Latency on subsequent requests is reduced since there is no time spent in the double handshakes required for gracefully closing TCP connections and holding the TIMEWAIT state, and in TCP's connection opening handshake, when reopening the connection."

I think the 4th point can be left intact without the TIME_WAIT add-on.

> 3. Section 6.1.2.1 Negotiation, second paragraph
>
> Change Type: Editorial clarification
> Rationale: The second paragraph of this section states:
>   " An HTTP/1.1 client MAY expect a connection to remain open, but would
>    decide to keep it open based on whether the response from a server
>    contains a Connection header field with the connection-token close."
>
> It is not clear what the intent of this sentence is. Does it imply that on the receipt of a response with a close token, the client will close the connection?

No, it indicates that the client should expect the connection to be
closed when it receives this response. This means it should still poll
it to detect the close, and should not send anything else over it when
it receives the full response. We should never expect a client to close
first for the TIME_WAIT issues discussed above.

> Does it also imply that if the response did not contain the close token, then the client would keep the connection open?

No, as it can never be assumed that any agent in the chain will kill a
connection open, this is just best effort from everyone. It means that
the client MAY keep the connection open unless there is a close token
in the Connection header.

> If this is the intent, then a clearer statement of it would help to exclude other interpretations, as the current text seems to allow the client latitude to close or not on either of these events.
>
> Proposed Additional text if the above interpretation is the intent:
> Add a sentence to clarify the intent at the end of the above quoted sentence:
> "If the response does not contain the close token the client will keep the connection open, otherwise, on receipt of the close token in the response, the client will close the connection."

It is not the intent. Also, be careful with the wording "the client will",
because it does not look like something mandatory for the client while it
implies that the server can safely rely on this. Prefer the MUST, SHOULD,
MAY etc... wording to indicate who is responsible for what.

> 4. Section 6.1.2.1 Negotiation, third paragraph (second paragraph on page 42)
>
> Change Type: Editorial clarification
> Rationale: The paragraph states:
>   "If either the client or the server sends the close token in the
>    Connection header field, that request becomes the last one for the
>    connection."
>
> This is similar to item 2 above. The problem is knowing what "that request" is in the case when the server includes the close token and pipelining occurs, and what is intended by the phrase "becomes the last one for the connection". We expect that the following is the intent:
> A. If the client receives a response with the close token, it will not send any more requests (as in item 2 above); and
> B. Once the server has sent a response with the close token, it will discard any further requests it receives.

I think both are true, indeed.

> Proposed Replacement text, given that previous items 2 and 3 are accepted
> Replace this sentence by:
> "Once the server has sent a response with the close token, it will discard any further requests it receives."

You removed the point related to the client's close token. I think it
should be better to add a sentence after the original one :
"Clients MUST not send any new request over a connection once the last
 one is identified, and servers MUST discard any new request received
 after the last one."

That's all for me now.

Thanks,
Willy

Received on Wednesday, 21 December 2011 01:20:57 UTC