RE: Split error codes in two

"Lubashev, Igor" <ilubashe@akamai.com> Wed, 13 September 2017 04:23 UTC

Return-Path: <ilubashe@akamai.com>
X-Original-To: quic@ietfa.amsl.com
Delivered-To: quic@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 101E3133529 for <quic@ietfa.amsl.com>; Tue, 12 Sep 2017 21:23:52 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -1.998
X-Spam-Level:
X-Spam-Status: No, score=-1.998 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HTML_MESSAGE=0.001, LOTS_OF_MONEY=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (2048-bit key) header.d=akamai.com
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id S9w7rPA6DnpZ for <quic@ietfa.amsl.com>; Tue, 12 Sep 2017 21:23:49 -0700 (PDT)
Received: from mx0b-00190b01.pphosted.com (mx0b-00190b01.pphosted.com [IPv6:2620:100:9005:57f::1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id DDE0A132964 for <quic@ietf.org>; Tue, 12 Sep 2017 21:23:48 -0700 (PDT)
Received: from pps.filterd (m0050102.ppops.net [127.0.0.1]) by m0050102.ppops.net-00190b01. (8.16.0.21/8.16.0.21) with SMTP id v8D4M2XP005653; Wed, 13 Sep 2017 05:23:38 +0100
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=akamai.com; h=from : to : cc : subject : date : message-id : references : in-reply-to : content-type : mime-version; s=jan2016.eng; bh=WfA8iwfuzK8xLnijbNMmXGdpUNgxDh34zzl7NnhhwRc=; b=GkhTYOxEjmVr+/isx4iX4lVtBI53F+9I9z2fQvBT6H0e7kBLuNCunhSqKZIpOtMT1Y4n IxYNYB1eYhGLFgr8s8TPOZoEIH+sQOCXLT2+UgKkoFONUuCdvlgVaPR/kXfS3djQ41e9 Jb9K+itR0u7crBC2DvAHo6kZinogQ4tnGk8NdeJoc1t7j0uOVmluplh17Ljk3kXB6Qp+ 7dsKAaiNEgOY8vmTbqDsQyoxt3/Rfx5oEwqYGvmlVitxR+qnv6GUYKSbJNDASchz3YaS LqTbf7mwaeHvJjvJanTMDgCtXmEXZCB2wAYWIia7D64o7ZWFBSDKmn8PfExdf9B/7Mg8 ZQ==
Received: from prod-mail-ppoint1 (prod-mail-ppoint1.akamai.com [184.51.33.18]) by m0050102.ppops.net-00190b01. with ESMTP id 2cx9sydmdb-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 13 Sep 2017 05:23:38 +0100
Received: from pps.filterd (prod-mail-ppoint1.akamai.com [127.0.0.1]) by prod-mail-ppoint1.akamai.com (8.16.0.21/8.16.0.21) with SMTP id v8D4Kf7t009995; Wed, 13 Sep 2017 00:23:37 -0400
Received: from email.msg.corp.akamai.com ([172.27.25.34]) by prod-mail-ppoint1.akamai.com with ESMTP id 2cwwqk4hmf-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Wed, 13 Sep 2017 00:23:37 -0400
Received: from USTX2EX-DAG1MB5.msg.corp.akamai.com (172.27.27.105) by ustx2ex-dag1mb5.msg.corp.akamai.com (172.27.27.105) with Microsoft SMTP Server (TLS) id 15.0.1263.5; Tue, 12 Sep 2017 23:23:35 -0500
Received: from USTX2EX-DAG1MB5.msg.corp.akamai.com ([172.27.27.105]) by ustx2ex-dag1mb5.msg.corp.akamai.com ([172.27.27.105]) with mapi id 15.00.1263.000; Tue, 12 Sep 2017 23:23:35 -0500
From: "Lubashev, Igor" <ilubashe@akamai.com>
To: Mike Bishop <Michael.Bishop@microsoft.com>, Jana Iyengar <jri@google.com>, Martin Thomson <martin.thomson@gmail.com>
CC: "Philipp S. Tiesel" <phils@in-panik.de>, Subodh Iyengar <subodh@fb.com>, Nick Harper <nharper@google.com>, QUIC WG <quic@ietf.org>, Victor Vasiliev <vasilvv@google.com>
Subject: RE: Split error codes in two
Thread-Topic: Split error codes in two
Thread-Index: AQHTJTn9U7CZmvfU3U+AKlwSnR9wwKKmV3WAgAASqICAAAONAIAA0yCAgAAOnACAAAMMAIAAAK4AgACXxwCAAJELAIABpR2AgABJmoCAAAS/AIAANHEAgAFsKYCABkENAP//wQ6Q
Date: Wed, 13 Sep 2017 04:23:35 +0000
Message-ID: <bca00829d58049fb8a644f3787011fca@ustx2ex-dag1mb5.msg.corp.akamai.com>
References: <CABkgnnWwGAyHzkST9o9ueVmBw3_TpJun=dv2X+HL2snXSZJgew@mail.gmail.com> <CAAZdMafBWFWtC7A60P1CMm_6nUnbW+_Tx_7re1bAo7Vx2kLdcA@mail.gmail.com> <CABkgnnWphw3k=f3==2y3AhexQCj9Py50SLSEH06nN3MN0SCerQ@mail.gmail.com> <CAAZdMacHC1HKhXMR4G9CKUOmYyQMsQBab+tampP-PG6n_jJZoA@mail.gmail.com> <CACdeXiLS7W8cJbnT=orHkcd9reH=8QqhOzxWnUEpWZmfcdvd2g@mail.gmail.com> <CAGD1bZa-h0ZVh7kUYQtG3r93eH6TqRXnQ6YXAcscCrCQHk8LeA@mail.gmail.com> <CABkgnnXMFUP_c+2r6YeJouJXanHd8tFcqDKgU=C9UF0stPcXOw@mail.gmail.com> <CAGD1bZZZG9L0_d7Tmo8vfdAx+=LU+yi97N42vKFGo82K16Zycw@mail.gmail.com> <05505C10-8737-4C58-BC91-E401D2659AF0@in-panik.de> <MWHPR21MB0141F305CCE2B686F09549F887970@MWHPR21MB0141.namprd21.prod.outlook.com> <CAGD1bZY5xo5Krn=U3SBVUCPU4x2UAOcv2AnvzaRac9qJGM9KBg@mail.gmail.com> <DM5PR15MB14497BB2F1971C5965882875B6940@DM5PR15MB1449.namprd15.prod.outlook.com> <CAGD1bZbnpCxjdaEV_m_5XWEjtjmdxYTGh2VBoS8AgZdhxfsDhw@mail.gmail.com> <CABkgnnWRy17vuFRGhpvLBCKte3WeCdGa1M1feOBygQv+-AB2+A@mail.gmail.com> <CAGD1bZZL-4HzArTQfWrC+CbHYsyB6Wdx4cbz7+0X7YOiuc-+Qg@mail.gmail.com> <BN6PR21MB01302C7E8A43AF9DB7A63335876E0@BN6PR21MB0130.namprd21.prod.outlook.com>
In-Reply-To: <BN6PR21MB01302C7E8A43AF9DB7A63335876E0@BN6PR21MB0130.namprd21.prod.outlook.com>
Accept-Language: en-US
Content-Language: en-US
X-MS-Has-Attach:
X-MS-TNEF-Correlator:
x-ms-exchange-transport-fromentityheader: Hosted
x-originating-ip: [172.19.32.252]
Content-Type: multipart/alternative; boundary="_000_bca00829d58049fb8a644f3787011fcaustx2exdag1mb5msgcorpak_"
MIME-Version: 1.0
X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-09-13_02:, , signatures=0
X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 spamscore=0 suspectscore=0 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1707230000 definitions=main-1709130066
X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-09-13_02:, , signatures=0
X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1011 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1707230000 definitions=main-1709130066
Archived-At: <https://mailarchive.ietf.org/arch/msg/quic/eTdSZ6LT8r4EJVY9-CETBAt8kLs>
X-BeenThere: quic@ietf.org
X-Mailman-Version: 2.1.22
Precedence: list
List-Id: Main mailing list of the IETF QUIC working group <quic.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/quic>, <mailto:quic-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/quic/>
List-Post: <mailto:quic@ietf.org>
List-Help: <mailto:quic-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/quic>, <mailto:quic-request@ietf.org?subject=subscribe>
X-List-Received-Date: Wed, 13 Sep 2017 04:23:52 -0000

This is a very good idea to decide what we want to model streams on.  Starting with well-known, simple abstractions seems like the best path to adoption.

There are two such abstractions that come to mind:


  1.  “TCP Stream sockets”.  These only support signaling “orderly” closing of the write direction.  Closing of the read direction can only be done via close(), but that may leave the write direction in an undefined state (writing will complete, unless there was unread data in the read buffer or any data is received after close – see RFC 1122 4.2.2.13 $3).


I think the current spec allows for QUIC API to emulate TCP stream socket abstraction.  Current spec  also adds signaling “abort” closing of the write direction (RST_STREAM does not require an immediate RST_STREAM in the opposite direction), although there was some talk of removing this feature.


  1.  “A POSIX pipe pair”, as Mike is proposing (one pair in each direction).  Connected pipes are very clean (‘symmetric’) abstractions, and they communicate close events (you close the ‘write’ pipe, ‘read’ pipe get EOS; you close the ‘read’ pipe, ‘write’ pipe gets an exception).



With read-direction close signaling, however, it is important to not to cause often-unnecessary STOP_SENDING frames sent for every common-case stream.close(). I think that could be done via one of the following ways:

  1.  Unidirectional streams. Send STOP_SENDING on close() by the receiver (if the steam is open).
  2.  API convention: “only send STOP_SENDING on stream.inputStream().close()”. On stream.close(), only send STOP_SENDING if there is unread data or new data comes in later.
  3.  Actually signal that read direction is closed in stream.close() by defining STREAM-with-FIN frame as “close both write and read directions” (common case).  Have separate frame types for WRITE_CLOSE, WRITE_ABORT (aka RST_STREAM), and READ_ABORT (aka STOP_SENDING).


From: Mike Bishop [mailto:Michael.Bishop@microsoft.com]
Sent: Tuesday, September 12, 2017 8:04 PM
To: Jana Iyengar <jri@google.com>; Martin Thomson <martin.thomson@gmail.com>
Cc: Philipp S. Tiesel <phils@in-panik.de>; Subodh Iyengar <subodh@fb.com>; Nick Harper <nharper@google.com>; QUIC WG <quic@ietf.org>; Victor Vasiliev <vasilvv@google.com>
Subject: RE: Split error codes in two

Jana and I were discussing this today, and part of the difference comes down to how you conceive of the API a QUIC implementation will expose.  My mental model has been that a stream/stream-pair consists of an InputStream and an OutputStream; you can read on one, you can write on the other.  For the write stream, you can write your data to completion and close the stream, or you can decide to abort writing.  The wire expressions of these are FIN and RST_STREAM, respectively.  For the read stream, you can read the incoming data to the end or you can abort reading and discard the remainder of the stream; the wire expression of this would be flow control updates and STOP_SENDING, respectively.  On the other side, receipt of a RST_STREAM surfaces as a read error and receipt of a STOP_SENDING surfaces as a write error.  (Jana commented that in this mental model it might be clearer to call the frames WRITE_ABORT and READ_ABORT.)

If we take Martin’s proposition that streams only close by application action, there would never be a write error surfaced to the application unless the underlying transport went away entirely.  Instead, it’s the responsibility of the application protocol to communicate (on another stream, in this case) that you should abort writing, even if you’ve already written to completion, and then to do so.  That implies that the application needs the ability to return to streams on which it’s done writing, in case it’s later asked to go back and reset them.

Much of our discussions around unidirectional streams, stream state transitions, etc. including the question of whether STOP_SENDING belongs at the transport layer, stem from the fact that we all have different implicit mental models of the functional surface QUIC exposes.  Perhaps we should take a step back and agree on that first, as I believe Christian has suggested in the past?

From: Jana Iyengar [mailto:jri@google.com]
Sent: Friday, September 8, 2017 5:34 PM
To: Martin Thomson <martin.thomson@gmail.com<mailto:martin.thomson@gmail.com>>
Cc: Subodh Iyengar <subodh@fb.com<mailto:subodh@fb.com>>; Mike Bishop <Michael.Bishop@microsoft.com<mailto:Michael.Bishop@microsoft.com>>; Philipp S. Tiesel <phils@in-panik.de<mailto:phils@in-panik.de>>; QUIC WG <quic@ietf.org<mailto:quic@ietf.org>>; Nick Harper <nharper@google.com<mailto:nharper@google.com>>; Victor Vasiliev <vasilvv@google.com<mailto:vasilvv@google.com>>
Subject: Re: Split error codes in two

On Thu, Sep 7, 2017 at 7:50 PM, Martin Thomson <martin.thomson@gmail.com<mailto:martin.thomson@gmail.com>> wrote:
On Fri, Sep 8, 2017 at 9:42 AM, Jana Iyengar <jri@google.com<mailto:jri@google.com>> wrote:
> I don't think it makes sense to design an app protocol that doesn't send a
> RST in response to a RST.

I've been told not to invoke this particular demon, but you just
invoked the Unidirectional streams problem.  I think that we get there
because of this meme that says that data in the one direction is
somehow necessarily bound to data in the other direction.  That's an
entirely constructed notion.  A useful construct at times, certainly,
but that's not the point here.

I think that's the most common use of a RST -- to close both directions.

So I disagree.  There are many protocols in which you send messages
(== streams) in one direction but not another.  One of the ways you
get into a unidirectional state in the current draft is to end one
side.  A FIN is only one way to do that, a unidirectional RST can be
faster and even superior in other ways.  The HTTP use case clearly
illustrates that.

FIN is the primary way in which half-close is achieved, which is what you're talking about. The HTTP use case is a complete one-off -- STOP_SENDING is an odd enough use case that I'm always left wondering who actually uses it.

Also, as Igor observes, we don't require a reciprocal RST_STREAM in
the current draft.

Yes, we don't. Recall that the RST_STREAM was, prior to the change that doesn't require reciprocity, a bidirectional signal, which was simplified to a unidirectional one, with the general expectation that apps would close the other side when they receive this signal from QUIC. It's surely going to be true of HTTP. It's possible for an app to receive a RST and then keep sending, but that is a use case I haven't seen in practice.