QUIC: added shutdown support in stream proxy.

This commit is contained in:
Vladimir Homutov 2021-09-23 16:25:49 +03:00
parent bbd05ae252
commit f5d0c6db67
3 changed files with 66 additions and 0 deletions

View File

@ -92,6 +92,7 @@ void ngx_quic_finalize_connection(ngx_connection_t *c, ngx_uint_t err,
void ngx_quic_shutdown_connection(ngx_connection_t *c, ngx_uint_t err,
const char *reason);
ngx_int_t ngx_quic_reset_stream(ngx_connection_t *c, ngx_uint_t err);
ngx_int_t ngx_quic_shutdown_stream(ngx_connection_t *c, int how);
uint32_t ngx_quic_version(ngx_connection_t *c);
ngx_int_t ngx_quic_handle_read_event(ngx_event_t *rev, ngx_uint_t flags);
ngx_int_t ngx_quic_handle_write_event(ngx_event_t *wev, size_t lowat);

View File

@ -252,6 +252,56 @@ ngx_quic_reset_stream(ngx_connection_t *c, ngx_uint_t err)
}
ngx_int_t
ngx_quic_shutdown_stream(ngx_connection_t *c, int how)
{
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;
}
wev = c->write;
if (wev->error) {
return NGX_OK;
}
qs = c->quic;
pc = qs->parent;
qc = ngx_quic_get_connection(pc);
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 shutdown", qs->id);
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);
wev->ready = 1;
wev->error = 1;
return NGX_OK;
}
static ngx_quic_stream_t *
ngx_quic_create_client_stream(ngx_connection_t *c, uint64_t id)
{

View File

@ -1767,6 +1767,21 @@ ngx_stream_proxy_process(ngx_stream_session_t *s, ngx_uint_t from_upstream,
if (dst->type == SOCK_STREAM && pscf->half_close
&& src->read->eof && !u->half_closed && !dst->buffered)
{
#if (NGX_STREAM_QUIC)
if (dst->quic) {
if (ngx_quic_shutdown_stream(dst, NGX_WRITE_SHUTDOWN)
!= NGX_OK)
{
ngx_stream_proxy_finalize(s,
NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
} else
#endif
if (ngx_shutdown_socket(dst->fd, NGX_WRITE_SHUTDOWN) == -1) {
ngx_connection_error(c, ngx_socket_errno,
ngx_shutdown_socket_n " failed");