[vlc-commits] http: track H2 connection send window

Rémi Denis-Courmont git at videolan.org
Tue Sep 24 21:00:45 CEST 2019


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sun Sep 22 18:03:10 2019 +0300| [be997f48bafcdfb6ba1918d774c18bc507b3a04d] | committer: Rémi Denis-Courmont

http: track H2 connection send window

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=be997f48bafcdfb6ba1918d774c18bc507b3a04d
---

 modules/access/http/h2conn.c       | 32 ++++++++++++++++++++++++++++++++
 modules/access/http/h2frame.c      |  2 ++
 modules/access/http/h2frame.h      |  1 +
 modules/access/http/h2frame_test.c |  7 +++++++
 4 files changed, 42 insertions(+)

diff --git a/modules/access/http/h2conn.c b/modules/access/http/h2conn.c
index f6110c768d..e71bca305c 100644
--- a/modules/access/http/h2conn.c
+++ b/modules/access/http/h2conn.c
@@ -56,6 +56,9 @@ struct vlc_h2_conn
     uint32_t next_id; /**< Next free stream identifier */
     bool released; /**< Connection released by owner */
 
+    uint32_t init_send_cwnd; /**< Initial send congestion window */
+    uint64_t send_cwnd; /**< Send congestion window */
+
     vlc_mutex_t lock; /**< State machine lock */
     vlc_thread_t thread; /**< Receive thread */
 };
@@ -450,6 +453,15 @@ error:
 
 /* Global/Connection frame callbacks */
 
+static void vlc_h2_initial_window_update(struct vlc_h2_conn *conn,
+                                         uint_fast32_t value)
+{
+    uint64_t delta = (uint64_t)value - conn->init_send_cwnd;
+
+    conn->init_send_cwnd = value;
+    conn->send_cwnd += delta;
+}
+
 /** Reports an HTTP/2 peer connection setting */
 static void vlc_h2_setting(void *ctx, uint_fast16_t id, uint_fast32_t value)
 {
@@ -457,6 +469,13 @@ static void vlc_h2_setting(void *ctx, uint_fast16_t id, uint_fast32_t value)
 
     vlc_http_dbg(CO(conn), "setting: %s (0x%04"PRIxFAST16"): %"PRIuFAST32,
                  vlc_h2_setting_name(id), id, value);
+
+    switch (id)
+    {
+        case VLC_H2_SETTING_INITIAL_WINDOW_SIZE:
+            vlc_h2_initial_window_update(conn, value);
+            break;
+    }
 }
 
 /** Reports end of HTTP/2 peer settings */
@@ -525,6 +544,16 @@ static void vlc_h2_window_status(void *ctx, uint32_t *restrict rcwd)
         *rcwd += 1 << 30;
 }
 
+static void vlc_h2_window_update(void *ctx, uint_fast32_t credit)
+{
+    struct vlc_h2_conn *conn = ctx;
+
+    conn->send_cwnd += credit;
+
+    vlc_http_dbg(CO(conn), "window update: +%"PRIuFAST32" to %"PRIu64,
+                 credit, conn->send_cwnd);
+}
+
 /** HTTP/2 frames parser callbacks table */
 static const struct vlc_h2_parser_cbs vlc_h2_parser_callbacks =
 {
@@ -534,6 +563,7 @@ static const struct vlc_h2_parser_cbs vlc_h2_parser_callbacks =
     vlc_h2_error,
     vlc_h2_reset,
     vlc_h2_window_status,
+    vlc_h2_window_update,
     vlc_h2_stream_lookup,
     vlc_h2_stream_error,
     vlc_h2_stream_headers,
@@ -732,6 +762,8 @@ struct vlc_http_conn *vlc_h2_conn_create(void *ctx, struct vlc_tls *tls)
     conn->streams = NULL;
     conn->next_id = 1; /* TODO: server side */
     conn->released = false;
+    conn->init_send_cwnd = VLC_H2_DEFAULT_INIT_WINDOW;
+    conn->send_cwnd = VLC_H2_DEFAULT_INIT_WINDOW;
 
     if (unlikely(conn->out == NULL))
         goto error;
diff --git a/modules/access/http/h2frame.c b/modules/access/http/h2frame.c
index 4a2b728a7f..4bb2c6472c 100644
--- a/modules/access/http/h2frame.c
+++ b/modules/access/http/h2frame.c
@@ -874,6 +874,8 @@ static int vlc_h2_parse_frame_window_update(struct vlc_h2_parser *p,
         return vlc_h2_stream_error(p, id, VLC_H2_PROTOCOL_ERROR);
     }
 
+    if (id == 0)
+        p->cbs->window_update(p->opaque, credit);
     return 0;
 }
 
diff --git a/modules/access/http/h2frame.h b/modules/access/http/h2frame.h
index 1b475a325c..1dd8b75819 100644
--- a/modules/access/http/h2frame.h
+++ b/modules/access/http/h2frame.h
@@ -105,6 +105,7 @@ struct vlc_h2_parser_cbs
     void (*error)(void *ctx, uint_fast32_t code);
     int  (*reset)(void *ctx, uint_fast32_t last_seq, uint_fast32_t code);
     void (*window_status)(void *ctx, uint32_t *rcwd);
+    void (*window_update)(void *ctx, uint_fast32_t credit);
 
     void *(*stream_lookup)(void *ctx, uint_fast32_t id);
     int  (*stream_error)(void *ctx, uint_fast32_t id, uint_fast32_t code);
diff --git a/modules/access/http/h2frame_test.c b/modules/access/http/h2frame_test.c
index 677a379284..878026b8ca 100644
--- a/modules/access/http/h2frame_test.c
+++ b/modules/access/http/h2frame_test.c
@@ -128,6 +128,12 @@ static void vlc_h2_window_status(void *ctx, uint32_t *rcwd)
     *rcwd = (1u << 31) - 1;
 }
 
+static void vlc_h2_window_update(void *ctx, uint_fast32_t credit)
+{
+    assert(ctx == CTX);
+    assert(credit == 0x1000);
+}
+
 #define STREAM_ID 0x76543210
 char stream_cookie; /* dummy unique value */
 
@@ -328,6 +334,7 @@ static const struct vlc_h2_parser_cbs vlc_h2_frame_test_callbacks =
     vlc_h2_error,
     vlc_h2_reset,
     vlc_h2_window_status,
+    vlc_h2_window_update,
     vlc_h2_stream_lookup,
     vlc_h2_stream_error,
     vlc_h2_stream_headers,



More information about the vlc-commits mailing list