Re: [hybi] Reliable message delivery (was Re: Technical feedback.)

Jamie Lokier <jamie@shareable.org> Tue, 02 February 2010 01:25 UTC

Return-Path: <jamie@shareable.org>
X-Original-To: hybi@core3.amsl.com
Delivered-To: hybi@core3.amsl.com
Received: from localhost (localhost [127.0.0.1]) by core3.amsl.com (Postfix) with ESMTP id BDBD73A69CA for <hybi@core3.amsl.com>; Mon, 1 Feb 2010 17:25:06 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.459
X-Spam-Level:
X-Spam-Status: No, score=-2.459 tagged_above=-999 required=5 tests=[AWL=0.140, BAYES_00=-2.599]
Received: from mail.ietf.org ([64.170.98.32]) by localhost (core3.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id YU33pAXVIq4o for <hybi@core3.amsl.com>; Mon, 1 Feb 2010 17:25:05 -0800 (PST)
Received: from mail2.shareable.org (mail2.shareable.org [80.68.89.115]) by core3.amsl.com (Postfix) with ESMTP id B5EDE3A693E for <hybi@ietf.org>; Mon, 1 Feb 2010 17:25:05 -0800 (PST)
Received: from jamie by mail2.shareable.org with local (Exim 4.63) (envelope-from <jamie@shareable.org>) id 1Nc7WI-0002HZ-34; Tue, 02 Feb 2010 01:25:34 +0000
Date: Tue, 02 Feb 2010 01:25:34 +0000
From: Jamie Lokier <jamie@shareable.org>
To: "Thomson, Martin" <Martin.Thomson@andrew.com>
Message-ID: <20100202012534.GB32743@shareable.org>
References: <5c902b9e1001292310l5442d476n8375139f3480671b@mail.gmail.com> <26D406E7-2319-476E-9ADF-80D84200C270@apple.com> <5c902b9e1001292333k79569316lf371938c9aa766@mail.gmail.com> <128BFD31-9835-47B1-B7A9-F20F5CDA8D8C@apple.com> <20100130144936.GD19124@shareable.org> <5c902b9e1001301552n6efb7969o34110373e3ab4945@mail.gmail.com> <4B672C9D.9010205@ericsson.com> <op.u7gy9bag64w2qv@annevk-t60> <96935605-E8B8-4718-B60F-570FD2C199E4@apple.com> <8B0A9FCBB9832F43971E38010638454F032E5065ED@SISPE7MB1.commscope.com>
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Disposition: inline
In-Reply-To: <8B0A9FCBB9832F43971E38010638454F032E5065ED@SISPE7MB1.commscope.com>
User-Agent: Mutt/1.5.13 (2006-08-11)
Cc: Hybi <hybi@ietf.org>
Subject: Re: [hybi] Reliable message delivery (was Re: Technical feedback.)
X-BeenThere: hybi@ietf.org
X-Mailman-Version: 2.1.9
Precedence: list
List-Id: Server-Initiated HTTP <hybi.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/listinfo/hybi>, <mailto:hybi-request@ietf.org?subject=unsubscribe>
List-Archive: <http://www.ietf.org/mail-archive/web/hybi>
List-Post: <mailto:hybi@ietf.org>
List-Help: <mailto:hybi-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/hybi>, <mailto:hybi-request@ietf.org?subject=subscribe>
X-List-Received-Date: Tue, 02 Feb 2010 01:25:06 -0000

Thomson, Martin wrote:
> > If A wants to close the connection it does the following:
> > 
> > 1) transmits 0xFF 0x00 to B.
> > 2) Calls shutdown(SHUT_WR) on its socket (instead of close)
> > 3) Reads anything else transmitted from B until it gets EOF, at which
> > point it calls close().
> > 
> > When B receives 0xFF 0x00, it sends any remaining buffered messages and
> > calls close.
> 
> Anne's described solution works better.
> 
> The 0xff00 frame is the indication that close() can be called
> safely.  Besides, it's two extra octets, hardly an imposition on
> either end.

The major cost on most networks is packet counts and round trips, not
bytes.  (Bytes of large messages, yes, but that is something else.)

Anne's solution adds an extra packet, because Martin's can combine the
first data and TCP FIN into a single packet, although it depends on
TCP implementation as well as the TCP_NODELAY (Nagle) setting at that
moment, and whether there is already other data buffered to send.

The minimal version does not need a frame at all:

  1) Calls shutdown(SHUT_WR).
  2) Reads anything else transmitted from B until it gets EOF, at which
     point it calls close().

Meanwhile, B receives an EOF and calls close() immediately.

That is fine for TCP; the 0xff 0x00 is redundant.

But we must also pay attention to some important reality: There will
be implementations which run over pipes (CGI), internal APIs and so on
which don't support the half-closed semantic.  There will be relays
from TCP WebSocket directly to those other forms.  It does nobody any
favours to define a protocol which only works over TCP and forces
those implementations to have to invent something extra and shoehorn
it in.

Note, there are some ancient TCP implementations which don't support
the shutdown() call.  That might be why it's not mentioned in HTTP.

My vote would for an endpoint to be able to send *either* a close
frame 0xff 0x00, or EOF as a result of shutdown(SHUT_WR), or both, as
it chooses.  Receivers would treat EOF and close-frame the same.

(Though it should be considered how that would affect a simple
WebSocket to CGI relay - the relay must parse every byte because of
the sentinel-delimited frames, to inject/strip 0xff 0x00 where
needed without doing so in the middle of a truncated message.)

Please note: The close-frame is *not* for acknowledgement of prior
messages.  It is a mechanism to prevent closes from turning into
"connection reset" TCP errors and the data-discarding behaviour.  It
would be *most unwise* of an endpoint to refuse to send the
close-frame (or shutdown) because it was keeping it to acknowledge an
expected message - because that would force the other end to keep a
connection open for a long timeout, when receiving close and lack of
an expected message is precisely a situation when connections should
be closed quickly because an unrecoverable error has occured.

-- Jamie