aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/event/quic/ngx_event_quic.h3
-rw-r--r--src/event/quic/ngx_event_quic_streams.c75
-rw-r--r--src/http/modules/ngx_http_quic_module.c3
-rw-r--r--src/stream/ngx_stream_quic_module.c3
4 files changed, 80 insertions, 4 deletions
diff --git a/src/event/quic/ngx_event_quic.h b/src/event/quic/ngx_event_quic.h
index 839570af0..1007c491d 100644
--- a/src/event/quic/ngx_event_quic.h
+++ b/src/event/quic/ngx_event_quic.h
@@ -61,6 +61,9 @@ typedef struct {
ngx_flag_t retry;
ngx_flag_t gso_enabled;
ngx_str_t host_key;
+ ngx_int_t stream_close_code;
+ ngx_int_t stream_reject_code_uni;
+ ngx_int_t stream_reject_code_bidi;
u_char av_token_key[NGX_QUIC_AV_KEY_LEN];
u_char sr_token_key[NGX_QUIC_SR_KEY_LEN];
} ngx_quic_conf_t;
diff --git a/src/event/quic/ngx_event_quic_streams.c b/src/event/quic/ngx_event_quic_streams.c
index 68f6b867c..bcb10d74d 100644
--- a/src/event/quic/ngx_event_quic_streams.c
+++ b/src/event/quic/ngx_event_quic_streams.c
@@ -15,6 +15,7 @@
static ngx_quic_stream_t *ngx_quic_create_client_stream(ngx_connection_t *c,
uint64_t id);
+static ngx_int_t ngx_quic_reject_stream(ngx_connection_t *c, uint64_t id);
static ngx_int_t ngx_quic_init_stream(ngx_quic_stream_t *qs);
static void ngx_quic_init_streams_handler(ngx_connection_t *c);
static ngx_quic_stream_t *ngx_quic_create_stream(ngx_connection_t *c,
@@ -377,8 +378,13 @@ ngx_quic_create_client_stream(ngx_connection_t *c, uint64_t id)
for ( /* void */ ; min_id < id; min_id += 0x04) {
qs = ngx_quic_create_stream(c, min_id);
+
if (qs == NULL) {
- return NULL;
+ if (ngx_quic_reject_stream(c, min_id) != NGX_OK) {
+ return NULL;
+ }
+
+ continue;
}
if (ngx_quic_init_stream(qs) != NGX_OK) {
@@ -390,7 +396,66 @@ ngx_quic_create_client_stream(ngx_connection_t *c, uint64_t id)
}
}
- return ngx_quic_create_stream(c, id);
+ qs = ngx_quic_create_stream(c, id);
+
+ if (qs == NULL) {
+ if (ngx_quic_reject_stream(c, id) != NGX_OK) {
+ return NULL;
+ }
+
+ return NGX_QUIC_STREAM_GONE;
+ }
+
+ return qs;
+}
+
+
+static ngx_int_t
+ngx_quic_reject_stream(ngx_connection_t *c, uint64_t id)
+{
+ uint64_t code;
+ ngx_quic_frame_t *frame;
+ ngx_quic_connection_t *qc;
+
+ qc = ngx_quic_get_connection(c);
+
+ code = (id & NGX_QUIC_STREAM_UNIDIRECTIONAL)
+ ? qc->conf->stream_reject_code_uni
+ : qc->conf->stream_reject_code_bidi;
+
+ if (code == 0) {
+ return NGX_DECLINED;
+ }
+
+ ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "quic stream id:0x%xL reject err:0x%xL", id, code);
+
+ frame = ngx_quic_alloc_frame(c);
+ if (frame == NULL) {
+ return NGX_ERROR;
+ }
+
+ frame->level = ssl_encryption_application;
+ frame->type = NGX_QUIC_FT_RESET_STREAM;
+ frame->u.reset_stream.id = id;
+ frame->u.reset_stream.error_code = code;
+ frame->u.reset_stream.final_size = 0;
+
+ ngx_quic_queue_frame(qc, frame);
+
+ frame = ngx_quic_alloc_frame(c);
+ if (frame == NULL) {
+ return NGX_ERROR;
+ }
+
+ frame->level = ssl_encryption_application;
+ frame->type = NGX_QUIC_FT_STOP_SENDING;
+ frame->u.stop_sending.id = id;
+ frame->u.stop_sending.error_code = code;
+
+ ngx_quic_queue_frame(qc, frame);
+
+ return NGX_OK;
}
@@ -866,7 +931,9 @@ ngx_quic_stream_cleanup_handler(void *data)
if ((qs->id & NGX_QUIC_STREAM_SERVER_INITIATED) == 0
|| (qs->id & NGX_QUIC_STREAM_UNIDIRECTIONAL) == 0)
{
- if (!c->read->pending_eof && !c->read->error) {
+ if (!c->read->pending_eof && !c->read->error
+ && qc->conf->stream_close_code)
+ {
frame = ngx_quic_alloc_frame(pc);
if (frame == NULL) {
goto done;
@@ -875,7 +942,7 @@ ngx_quic_stream_cleanup_handler(void *data)
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 = 0x100; /* HTTP/3 no error */
+ frame->u.stop_sending.error_code = qc->conf->stream_close_code;
ngx_quic_queue_frame(qc, frame);
}
diff --git a/src/http/modules/ngx_http_quic_module.c b/src/http/modules/ngx_http_quic_module.c
index 9e6d17ead..323ee2ead 100644
--- a/src/http/modules/ngx_http_quic_module.c
+++ b/src/http/modules/ngx_http_quic_module.c
@@ -314,6 +314,7 @@ ngx_http_quic_create_srv_conf(ngx_conf_t *cf)
* conf->tp.sr_enabled = 0
* conf->tp.preferred_address = NULL
* conf->host_key = { 0, NULL }
+ * cong->stream_reject_code_uni = 0;
*/
conf->tp.max_idle_timeout = NGX_CONF_UNSET_MSEC;
@@ -331,6 +332,8 @@ ngx_http_quic_create_srv_conf(ngx_conf_t *cf)
conf->retry = NGX_CONF_UNSET;
conf->gso_enabled = NGX_CONF_UNSET;
+ conf->stream_close_code = NGX_HTTP_V3_ERR_NO_ERROR;
+ conf->stream_reject_code_bidi = NGX_HTTP_V3_ERR_REQUEST_REJECTED;
return conf;
}
diff --git a/src/stream/ngx_stream_quic_module.c b/src/stream/ngx_stream_quic_module.c
index b40b17c93..7ad96a11c 100644
--- a/src/stream/ngx_stream_quic_module.c
+++ b/src/stream/ngx_stream_quic_module.c
@@ -241,6 +241,9 @@ ngx_stream_quic_create_srv_conf(ngx_conf_t *cf)
* conf->tp.retry_scid = { 0, NULL };
* conf->tp.preferred_address = NULL
* conf->host_key = { 0, NULL }
+ * conf->stream_close_code = 0;
+ * conf->stream_reject_code_uni = 0;
+ * conf->stream_reject_code_bidi= 0;
*/
conf->tp.max_idle_timeout = NGX_CONF_UNSET_MSEC;