h2 proxy and connection flow control

Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> Thu, 21 August 2014 13:44 UTC

Return-Path: <ietf-http-wg-request@listhub.w3.org>
X-Original-To: ietfarch-httpbisa-archive-bis2Juki@ietfa.amsl.com
Delivered-To: ietfarch-httpbisa-archive-bis2Juki@ietfa.amsl.com
Received: from localhost (ietfa.amsl.com [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id F1B311A02F8 for <ietfarch-httpbisa-archive-bis2Juki@ietfa.amsl.com>; Thu, 21 Aug 2014 06:44:07 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -7.669
X-Spam-Level:
X-Spam-Status: No, score=-7.669 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, RCVD_IN_DNSWL_HI=-5, RP_MATCHES_RCVD=-0.668, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001] autolearn=ham
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 muUT0B1I-ABg for <ietfarch-httpbisa-archive-bis2Juki@ietfa.amsl.com>; Thu, 21 Aug 2014 06:44:06 -0700 (PDT)
Received: from frink.w3.org (frink.w3.org [128.30.52.56]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 3E6021A02F5 for <httpbisa-archive-bis2Juki@lists.ietf.org>; Thu, 21 Aug 2014 06:43:59 -0700 (PDT)
Received: from lists by frink.w3.org with local (Exim 4.72) (envelope-from <ietf-http-wg-request@listhub.w3.org>) id 1XKSbL-000837-HY for ietf-http-wg-dist@listhub.w3.org; Thu, 21 Aug 2014 13:40:27 +0000
Resent-Date: Thu, 21 Aug 2014 13:40:27 +0000
Resent-Message-Id: <E1XKSbL-000837-HY@frink.w3.org>
Received: from lisa.w3.org ([128.30.52.41]) by frink.w3.org with esmtp (Exim 4.72) (envelope-from <tatsuhiro.t@gmail.com>) id 1XKSao-0006Wf-8y for ietf-http-wg@listhub.w3.org; Thu, 21 Aug 2014 13:39:54 +0000
Received: from mail-ig0-f173.google.com ([209.85.213.173]) by lisa.w3.org with esmtps (TLS1.0:RSA_ARCFOUR_SHA1:16) (Exim 4.72) (envelope-from <tatsuhiro.t@gmail.com>) id 1XKSan-0001Rw-3D for ietf-http-wg@w3.org; Thu, 21 Aug 2014 13:39:54 +0000
Received: by mail-ig0-f173.google.com with SMTP id h18so13307287igc.6 for <ietf-http-wg@w3.org>; Thu, 21 Aug 2014 06:39:27 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:from:date:message-id:subject:to:content-type; bh=eqLRPJ0a0wvPhWlTCWBdnSP+xrAWLTLcLO6N06w8ReI=; b=QwA4ycp3zRLfXgrS6yGdV6SDkOfAlHbzamndobkE5AO1K0s+PH8Nc2cZr77YgQI0o4 uDXh481G6r72gZpWta1IecPlTmGooZ6P5+1suNhXhSX48bxyEu5cR9lAbm0oaax5RPdQ Gk+47rPW8zLYdaAsJ+qhBdabmv5XtyqzGSv26ZqSwNRTNE1maF0Tk2CUPIHII6bydjt8 XZQN20t7b8IwZQiBLguUPG3+iNQ/stiQSp8MIy6NO0GTiDHGau94TFDW67YpKO/dWE5B r+64A4u2oOJVG+zWd2RaYlANz0nB1q+8CwX+D74bvCuVwyiiWOLRJ89xowoYnZikCnOt iEQg==
X-Received: by 10.43.111.6 with SMTP id em6mr3688386icc.21.1408628367051; Thu, 21 Aug 2014 06:39:27 -0700 (PDT)
MIME-Version: 1.0
Received: by 10.64.31.201 with HTTP; Thu, 21 Aug 2014 06:39:06 -0700 (PDT)
From: Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
Date: Thu, 21 Aug 2014 22:39:06 +0900
Message-ID: <CAPyZ6=+9sEFaaEBHSvhbzck6mLthatDVamMckYfnUXVMhVbiVg@mail.gmail.com>
To: HTTP <ietf-http-wg@w3.org>
Content-Type: multipart/alternative; boundary="bcaec517186570af0c050123d90d"
Received-SPF: pass client-ip=209.85.213.173; envelope-from=tatsuhiro.t@gmail.com; helo=mail-ig0-f173.google.com
X-W3C-Hub-Spam-Status: No, score=-3.5
X-W3C-Hub-Spam-Report: AWL=-2.730, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, FREEMAIL_FROM=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-0.7, SPF_PASS=-0.001
X-W3C-Scan-Sig: lisa.w3.org 1XKSan-0001Rw-3D 361fff9d13237880c7ddbcb59174b3e9
X-Original-To: ietf-http-wg@w3.org
Subject: h2 proxy and connection flow control
Archived-At: <http://www.w3.org/mid/CAPyZ6=+9sEFaaEBHSvhbzck6mLthatDVamMckYfnUXVMhVbiVg@mail.gmail.com>
Resent-From: ietf-http-wg@w3.org
X-Mailing-List: <ietf-http-wg@w3.org> archive/latest/26687
X-Loop: ietf-http-wg@w3.org
Resent-Sender: ietf-http-wg-request@w3.org
Precedence: list
List-Id: <ietf-http-wg.w3.org>
List-Help: <http://www.w3.org/Mail/>
List-Post: <mailto:ietf-http-wg@w3.org>
List-Unsubscribe: <mailto:ietf-http-wg-request@w3.org?subject=unsubscribe>

I'm not sure this is already discussed, but I found a case where
stalling single stream will stall all streams in entire session
when a h2 proxy is involved while playing with h2 proxy.

Here is an example setup of the scenario:

+---------+            +----------+            +---------+
|         |+---------->| Frontend |+---------->|         |
| Browser |            | Proxy    |            | Backend |
|         |<----------+|          |<-----------|         |
+---------+            +----------+            +---------+

Browser, Frontend Proxy and Backend server all speak h2.  There
is 1 TCP connection between Browser and Frontend Proxy.  Also
there is 1 TCP connection between Frontend Proxy and Backend.
These connections are independent h2 sessions.

Browser uses 10MB receive window for stream and 10MB for
connection.  Frontend Proxy uses 64KB receive window for stream
and 64KB for connection.

Browser sends requests to Frontend Proxy, and then Frontend Proxy
issues request to Backend and sends back its response to Browser.

Now suppose that Browser issues a request to Frontend Proxy (this
is denoted by stream A).  Frontend Proxy relays its request to
Backend (this is denoted by stream B).  Suppose that response
body is 40MB.  Then Frontend Proxy sends back response for stream
A to Browser but at some point Browser stops sending stream
WIDOW_UPDATE for some reason (e.g. it is a streaming media and it
is not consumed by media player).  Eventually, Browser's receive
window for stream becomes 0.

Since Browser's receive window is 0, Frontend Proxy cannot send
more DATA for stream A to Browser.  Meanwhile, Frontend Proxy
continues to receive DATA for stream B from Backend.  Since
stream A's stream window is 0, Frontend Proxy cannot proceed and
just buffer the received data and eventually Frontend Proxy's
receive window for connection becomes 0.

After this happens, Browser can still issue new request, but
Backend cannot send response to Frontend Proxy because its recive
window is 0.  This means that if Browser stalls one stream, it
stalls all streams in entire session.

+---------+            +----------+            +---------+
|         |+---------->| Frontend |+---------->|         |
| Browser |            | Proxy    |            | Backend |
|         |<----------+|          |<-----------|         |
+---------+     ^      +----------+     ^      +---------+
                |                       |
             stream A                all streams
            was stalled              was stalled
            due to stream            due to connection
           window is 0               window is 0

If a connection between Frontend Proxy and Backend is shared by
multiple clients, then things get worse, because if one client
stalls one stream, it affects all clients sharing the connection.

I think stalling stream by Browser is reasonable behaviour and
not a bug, because it just means that data is not consumed
yet. Or else, this is just another "Don't do that" situation?

How do you deal with this issue? (or is it not an issue because
I'm completely wrong?)

Here is my observation:

o Effectively disable connection level flow control in proxy
  -- this is controversial because connection flow control is
     effective especially for proxy to limit its memory
     commitment.

o Actively timeout stalled stream by proxy
  -- this may work, but incurs delay before timeout.

o Innovate flow control algorithm not to cause this situation
  -- I'm not sure how it looks like.

Best regards,

Tatsuhiro Tsujikawa