Welcome! Log In Create A New Profile

Advanced

Re: [PATCH 3 of 3] QUIC: stream recv shutdown support

Roman Arutyunyan
November 26, 2021 08:12AM
On Thu, Nov 25, 2021 at 05:20:51PM +0300, Roman Arutyunyan wrote:
> # HG changeset patch
> # User Roman Arutyunyan <arut@nginx.com>
> # Date 1637695967 -10800
> # Tue Nov 23 22:32:47 2021 +0300
> # Branch quic
> # Node ID e1de02d829f7f85b1e2e6b289ec4c20318712321
> # Parent 3d2354bfa1a2a257b9f73772ad0836585be85a6c
> QUIC: stream recv shutdown support.
>
> Recv shutdown sends STOP_SENDING to client. Both send and recv shutdown
> functions are now called from stream cleanup handler. While here, setting
> c->read->pending_eof is moved down to fix recv shutdown in the cleanup handler.

This definitely needs some improvement. Now it's two patches.

[..]

--
Roman Arutyunyan
# HG changeset patch
# User Roman Arutyunyan <arut@nginx.com>
# Date 1637931593 -10800
# Fri Nov 26 15:59:53 2021 +0300
# Branch quic
# Node ID c2fa3e7689a4e286f45ccbac2288ade5966273b8
# Parent 3d2354bfa1a2a257b9f73772ad0836585be85a6c
QUIC: do not shutdown write part of a client uni stream.

diff --git a/src/event/quic/ngx_event_quic_streams.c b/src/event/quic/ngx_event_quic_streams.c
--- a/src/event/quic/ngx_event_quic_streams.c
+++ b/src/event/quic/ngx_event_quic_streams.c
@@ -267,13 +267,20 @@ ngx_quic_shutdown_stream(ngx_connection_
return NGX_OK;
}

+ qs = c->quic;
+
+ if ((qs->id & NGX_QUIC_STREAM_SERVER_INITIATED) == 0
+ && (qs->id & NGX_QUIC_STREAM_UNIDIRECTIONAL))
+ {
+ return NGX_OK;
+ }
+
wev = c->write;

if (wev->error) {
return NGX_OK;
}

- qs = c->quic;
pc = qs->parent;
qc = ngx_quic_get_connection(pc);

# HG changeset patch
# User Roman Arutyunyan <arut@nginx.com>
# Date 1637932014 -10800
# Fri Nov 26 16:06:54 2021 +0300
# Branch quic
# Node ID ed0cefd9fc434a7593f2f9e4b9a98ce65aaf05e9
# Parent c2fa3e7689a4e286f45ccbac2288ade5966273b8
QUIC: write and full stream shutdown support.

Full stream shutdown is now called from stream cleanup handler instead of
explicitly sending frames. The call is moved up not to be influenced by
setting c->read->pending_eof, which was erroneously set too early.

diff --git a/src/event/quic/ngx_event_quic_streams.c b/src/event/quic/ngx_event_quic_streams.c
--- a/src/event/quic/ngx_event_quic_streams.c
+++ b/src/event/quic/ngx_event_quic_streams.c
@@ -13,6 +13,8 @@
#define NGX_QUIC_STREAM_GONE (void *) -1


+static ngx_int_t ngx_quic_shutdown_stream_send(ngx_connection_t *c);
+static ngx_int_t ngx_quic_shutdown_stream_recv(ngx_connection_t *c);
static ngx_quic_stream_t *ngx_quic_get_stream(ngx_connection_t *c, uint64_t id);
static ngx_int_t ngx_quic_reject_stream(ngx_connection_t *c, uint64_t id);
static void ngx_quic_init_stream_handler(ngx_event_t *ev);
@@ -257,16 +259,31 @@ ngx_quic_reset_stream(ngx_connection_t *
ngx_int_t
ngx_quic_shutdown_stream(ngx_connection_t *c, int how)
{
+ if (how == NGX_RW_SHUTDOWN || how == NGX_WRITE_SHUTDOWN) {
+ if (ngx_quic_shutdown_stream_send(c) != NGX_OK) {
+ return NGX_ERROR;
+ }
+ }
+
+ if (how == NGX_RW_SHUTDOWN || how == NGX_READ_SHUTDOWN) {
+ if (ngx_quic_shutdown_stream_recv(c) != NGX_OK) {
+ return NGX_ERROR;
+ }
+ }
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_quic_shutdown_stream_send(ngx_connection_t *c)
+{
ngx_event_t *wev;
ngx_connection_t *pc;
ngx_quic_frame_t *frame;
ngx_quic_stream_t *qs;
ngx_quic_connection_t *qc;

- if (how != NGX_WRITE_SHUTDOWN) {
- return NGX_OK;
- }
-
qs = c->quic;

if ((qs->id & NGX_QUIC_STREAM_SERVER_INITIATED) == 0
@@ -290,7 +307,7 @@ ngx_quic_shutdown_stream(ngx_connection_
}

ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "quic stream id:0x%xL shutdown", qs->id);
+ "quic stream id:0x%xL send shutdown", qs->id);

frame->level = ssl_encryption_application;
frame->type = NGX_QUIC_FT_STREAM;
@@ -311,6 +328,55 @@ ngx_quic_shutdown_stream(ngx_connection_
}


+static ngx_int_t
+ngx_quic_shutdown_stream_recv(ngx_connection_t *c)
+{
+ ngx_event_t *rev;
+ ngx_connection_t *pc;
+ ngx_quic_frame_t *frame;
+ ngx_quic_stream_t *qs;
+ ngx_quic_connection_t *qc;
+
+ qs = c->quic;
+
+ if ((qs->id & NGX_QUIC_STREAM_SERVER_INITIATED)
+ && (qs->id & NGX_QUIC_STREAM_UNIDIRECTIONAL))
+ {
+ return NGX_OK;
+ }
+
+ rev = c->read;
+
+ if (rev->pending_eof || rev->error) {
+ return NGX_OK;
+ }
+
+ pc = qs->parent;
+ qc = ngx_quic_get_connection(pc);
+
+ if (qc->conf->stream_close_code == 0) {
+ return NGX_OK;
+ }
+
+ frame = ngx_quic_alloc_frame(pc);
+ if (frame == NULL) {
+ return NGX_ERROR;
+ }
+
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "quic stream id:0x%xL recv shutdown", qs->id);
+
+ frame->level = ssl_encryption_application;
+ frame->type = NGX_QUIC_FT_STOP_SENDING;
+ frame->u.stop_sending.id = qs->id;
+ frame->u.stop_sending.error_code = qc->conf->stream_close_code;
+
+ ngx_quic_queue_frame(qc, frame);
+
+ return NGX_OK;
+}
+
+
static ngx_quic_stream_t *
ngx_quic_get_stream(ngx_connection_t *c, uint64_t id)
{
@@ -925,30 +991,12 @@ ngx_quic_stream_cleanup_handler(void *da
goto done;
}

+ (void) ngx_quic_shutdown_stream(c, NGX_RW_SHUTDOWN);
+
c->read->pending_eof = 1;

(void) ngx_quic_update_flow(c, qs->recv_last);

- if ((qs->id & NGX_QUIC_STREAM_SERVER_INITIATED) == 0
- || (qs->id & NGX_QUIC_STREAM_UNIDIRECTIONAL) == 0)
- {
- if (!c->read->pending_eof && !c->read->error
- && qc->conf->stream_close_code)
- {
- frame = ngx_quic_alloc_frame(pc);
- if (frame == NULL) {
- goto done;
- }
-
- frame->level = ssl_encryption_application;
- frame->type = NGX_QUIC_FT_STOP_SENDING;
- frame->u.stop_sending.id = qs->id;
- frame->u.stop_sending.error_code = qc->conf->stream_close_code;
-
- ngx_quic_queue_frame(qc, frame);
- }
- }
-
if ((qs->id & NGX_QUIC_STREAM_SERVER_INITIATED) == 0) {
frame = ngx_quic_alloc_frame(pc);
if (frame == NULL) {
@@ -968,37 +1016,8 @@ ngx_quic_stream_cleanup_handler(void *da
}

ngx_quic_queue_frame(qc, frame);
-
- if (qs->id & NGX_QUIC_STREAM_UNIDIRECTIONAL) {
- /* do not send fin for client unidirectional streams */
- goto done;
- }
}

- if (c->write->error) {
- goto done;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "quic stream id:0x%xL send fin", qs->id);
-
- frame = ngx_quic_alloc_frame(pc);
- if (frame == NULL) {
- goto done;
- }
-
- frame->level = ssl_encryption_application;
- frame->type = NGX_QUIC_FT_STREAM;
- frame->u.stream.off = 1;
- frame->u.stream.len = 1;
- frame->u.stream.fin = 1;
-
- frame->u.stream.stream_id = qs->id;
- frame->u.stream.offset = c->sent;
- frame->u.stream.length = 0;
-
- ngx_quic_queue_frame(qc, frame);
-
done:

(void) ngx_quic_output(pc);
diff --git a/src/os/unix/ngx_socket.h b/src/os/unix/ngx_socket.h
--- a/src/os/unix/ngx_socket.h
+++ b/src/os/unix/ngx_socket.h
@@ -13,6 +13,8 @@


#define NGX_WRITE_SHUTDOWN SHUT_WR
+#define NGX_READ_SHUTDOWN SHUT_RD
+#define NGX_RW_SHUTDOWN SHUT_RDWR

typedef int ngx_socket_t;

_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

[PATCH 0 of 3] Misc QUIC stream patches

Roman Arutyunyan 376 November 25, 2021 09:22AM

[PATCH 1 of 3] QUIC: post stream events instead of calling their handlers

Roman Arutyunyan 89 November 25, 2021 09:22AM

Re: [PATCH 1 of 3] QUIC: post stream events instead of calling their handlers

Sergey Kandaurov 151 December 06, 2021 07:38AM

Re: [PATCH 1 of 3] QUIC: post stream events instead of calling their handlers

Roman Arutyunyan 96 December 13, 2021 07:20AM

[PATCH 2 of 3] QUIC: simplified stream initialization

Roman Arutyunyan 221 November 25, 2021 09:22AM

Re: [PATCH 2 of 3] QUIC: simplified stream initialization

Sergey Kandaurov 94 December 10, 2021 09:02AM

[PATCH 3 of 3] QUIC: stream recv shutdown support

Roman Arutyunyan 142 November 25, 2021 09:22AM

Re: [PATCH 3 of 3] QUIC: stream recv shutdown support

Roman Arutyunyan 330 November 26, 2021 08:12AM

Re: [PATCH 3 of 3] QUIC: stream recv shutdown support

Vladimir Homutov 118 December 10, 2021 02:40AM

Re: [PATCH 3 of 3] QUIC: stream recv shutdown support

Roman Arutyunyan 74 December 13, 2021 07:04AM

Re: [PATCH 3 of 3] QUIC: stream recv shutdown support

Vladimir Homutov 90 December 13, 2021 08:26AM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 225
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready