httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ben Laurie <...@gonzo.ben.algroup.co.uk>
Subject Re: Lingering close: a summary
Date Sun, 09 Feb 1997 22:38:39 GMT
Marc Slemko wrote:
> 
> On Sun, 9 Feb 1997, Ben Laurie wrote:
> 
> > First, thanks, Marc, for persisting for so long (if not so patiently ;-)
> > with this. I've finally understood, I hope, what exactly this is all
> > about. So, I'm going to summarize my understanding below. 
> > 
> > 1. The essential point is that when a connection is fully closed, if the
> > client is still sending data, then any amount of previously sent server
> > data can be lost at the client end. This is because of an ambiguity in
> > the TCP/IP protocol over the meaning of RST, and just generally not
> > catering for that situation (TCP/IP takes the view that if you close a
> > connection while traffic is still flowing both ways, then you meant to
> > abort the connection). 
> 
> Not "any amount" of perviously sent server data, just a certain amount as
> defined by what remains in the buffers on the client and what the last
> packet the server knows the client has ACKed. 

In other words, an arbitrary amount. Which is what I said. That is, we cannot
predict how much will be lost.

> 
> > 2. Error messages generated "early" (i.e. before all incoming data has been
> > read), followed by a connection close can, therefore, get lost.
> 
> Yes.
> 
> > 
> > 3. Such errors occur in PUTs, since we write the error and close.
> 
> Yes.
> 
> > 
> > 4. Such errors occur in piplelined keptalive connections, for the same
> > reason.  That is, we can send an error and close for request 1, then
> > lose that error because request 2 arrives. 
> 
> Yes, but there is also the keepalive timeout and any limit on the number
> of keepalive requests that also come into play.  It does not just involved
> error messages with keepalive requests.  Responses which close the
> connection are one of the things that can cause problems, and error
> messages are one of the things which can cause that.

Agreed. But not agreed that we cannot resolve all reasons for doing it.

> 
> > 5. The problem with errors of this kind in keptalive connections is that
> > the client may repeat the request in another keptalive connection, and
> > hit the same problem, and so on ad infinitum (remembering that all the
> > subsequent requests also need a retry). 
> 
> That is one of the problems.  The simple fact that they occur is also
> wasteful since it just increases the traffic.

Agreed, but not a primary consideration. Functionality is more important than
efficiency.

> 
> > Now, there's the question of how to fix the problem. Several things
> > occur to me: 
> > 
> > A. Decide that TCP/IP is broken (there should be a way to reliably
> > deliver our data to the far end but still abort the input from it). This
> > is surely not fixable in v4, but may be worth mentioning to the v6
> > persons. Or maybe v6 does it anyway. 
> 
> I'm not sure you can say TCP is broken.  After all, lingering_close() does
> exactly what we want.  If you want it at the API level, SO_LINGER working
> as it should does it too.  TCP != the API.  The protocol itself isn't
> necessarily broken.

But it consumes resources like crazy (i.e. a whole copy of Apache, and a
network connection). A protocol level fix would be _much_ cheaper.

> 
> > B. Don't close keptalive connections when we send an error. I'm sure
> > there's a blindingly good reason we can't do this, but it escapes me. 
> 
> It can be done.  I suggested that the other day with a very small patch to
> do that, and Alexei gave three reasons why it won't work without more
> changes (for GETs; PUTs are another issue and are even more
> complicated...). Those problems can be worked around without much trouble; 
> if it had been brought up earlier, it would have been a good thing to do.
> But it wasn't and I think it is a bit late for 1.2 now.  And this still
> doesn't fix the whole problem, because it isn't just error messages that
> can close the connection.

No. This issue is critical. I don't think we can rule out this kind of fix for
1.2.

> 
> > C. Mandate in HTTP/1.1 that the first unsatisified request in an aborted
> > keepalive session must be retried alone, or at least without pipelining,
> > and explain carefully why. It would probably also be good to mandate
> > that the connection should be closed after a timeout (from both ends). 
> 
> This isn't an overly clean solution.  If the client behaves this way, from
> what I can see everything should work but I don't think this is a nice
> solution.  This still does not allow for automatic retries of requests
> that aren't idempotent.

You think that a half-close and reading an indefinite number of requests we are
not going to service is "nice"?

> 
> You also may be interested to note part of section 8.2 of RFC 2068:
> 
>    Upon receiving a method subject to these requirements from an
>    HTTP/1.1 (or later) client, an HTTP/1.1 (or later) server MUST either
>    respond with 100 (Continue) status and continue to read from the
>    input stream, or respond with an error status. If it responds with an
>    error status, it MAY close the transport (TCP) connection or it MAY
>    continue to read and discard the rest of the request. It MUST NOT
>    perform the requested method if it returns an error status.
> 
>    Clients SHOULD remember the version number of at least the most
>    recently used server; if an HTTP/1.1 client has seen an HTTP/1.1 or
>    later response from the server, and it sees the connection close
>    before receiving any status from the server, the client SHOULD retry
>    the request without user interaction so long as the request method is
>    idempotent (see section 9.1.2); other methods MUST NOT be
>    automatically retried, although user agents MAY offer a human
>    operator the choice of retrying the request.. If the client does
>    retry the request, the client
> 
>      o  MUST first send the request header fields, and then
> 
>      o  MUST wait for the server to respond with either a 100 (Continue)
>         response, in which case the client should continue, or with an
>         error status.
> 
>    If an HTTP/1.1 client has not seen an HTTP/1.1 or later response from
>    the server, it should assume that the server implements HTTP/1.0 or
>    older and will not use the 100 (Continue) response. If in this case
>    the client sees the connection close before receiving any status from
>    the server, the client SHOULD retry the request. If the client does
>    retry the request to this HTTP/1.0 server, it should use the
>    following "binary exponential backoff" algorithm to be assured of
> [...]
> 
> It goes on with some more interesting details.  Not all are applicable to
> our situation, but they should be kept in mind.
> 
> 

So what's the problem? HTTP/1.1 already appears to mandate solution C, which
leaves us clear to simply close the connection. Or did I miss something?

Cheers,

Ben (who will, one day, try to memorise the entire HTTP/1.1 spec).

-- 
Ben Laurie                Phone: +44 (181) 994 6435  Email: ben@algroup.co.uk
Freelance Consultant and  Fax:   +44 (181) 994 6472
Technical Director        URL: http://www.algroup.co.uk/Apache-SSL
A.L. Digital Ltd,         Apache Group member (http://www.apache.org)
London, England.          Apache-SSL author

Mime
View raw message