mirror of
https://github.com/nginx/nginx.git
synced 2025-02-25 18:55:26 -06:00
QUIC: added "quic" listen parameter.
The parameter allows processing HTTP/0.9-2 over QUIC. Also, introduced ngx_http_quic_module and moved QUIC settings there
This commit is contained in:
parent
a305de07e9
commit
b813b9ec35
@ -166,6 +166,7 @@ END
|
||||
exit 1
|
||||
fi
|
||||
|
||||
have=NGX_QUIC . auto/have
|
||||
fi
|
||||
|
||||
|
||||
|
20
auto/modules
20
auto/modules
@ -404,12 +404,9 @@ if [ $HTTP = YES ]; then
|
||||
ngx_module_type=HTTP
|
||||
|
||||
if [ $HTTP_V3 = YES ]; then
|
||||
USE_OPENSSL=YES
|
||||
USE_OPENSSL_QUIC=YES
|
||||
have=NGX_HTTP_V3 . auto/have
|
||||
have=NGX_HTTP_HEADERS . auto/have
|
||||
|
||||
HTTP_SSL=YES
|
||||
HTTP_QUIC=YES
|
||||
|
||||
# XXX for Huffman
|
||||
HTTP_V2=YES
|
||||
@ -696,6 +693,21 @@ if [ $HTTP = YES ]; then
|
||||
. auto/module
|
||||
fi
|
||||
|
||||
if [ $HTTP_QUIC = YES ]; then
|
||||
USE_OPENSSL_QUIC=YES
|
||||
have=NGX_HTTP_QUIC . auto/have
|
||||
HTTP_SSL=YES
|
||||
|
||||
ngx_module_name=ngx_http_quic_module
|
||||
ngx_module_incs=
|
||||
ngx_module_deps=src/http/modules/ngx_http_quic_module.h
|
||||
ngx_module_srcs=src/http/modules/ngx_http_quic_module.c
|
||||
ngx_module_libs=
|
||||
ngx_module_link=$HTTP_QUIC
|
||||
|
||||
. auto/module
|
||||
fi
|
||||
|
||||
if [ $HTTP_SSL = YES ]; then
|
||||
USE_OPENSSL=YES
|
||||
have=NGX_HTTP_SSL . auto/have
|
||||
|
@ -58,6 +58,7 @@ HTTP_CACHE=YES
|
||||
HTTP_CHARSET=YES
|
||||
HTTP_GZIP=YES
|
||||
HTTP_SSL=NO
|
||||
HTTP_QUIC=NO
|
||||
HTTP_V2=NO
|
||||
HTTP_V3=NO
|
||||
HTTP_SSI=YES
|
||||
@ -225,6 +226,7 @@ $0: warning: the \"--with-ipv6\" option is deprecated"
|
||||
--http-scgi-temp-path=*) NGX_HTTP_SCGI_TEMP_PATH="$value" ;;
|
||||
|
||||
--with-http_ssl_module) HTTP_SSL=YES ;;
|
||||
--with-http_quic_module) HTTP_QUIC=YES ;;
|
||||
--with-http_v2_module) HTTP_V2=YES ;;
|
||||
--with-http_v3_module) HTTP_V3=YES ;;
|
||||
--with-http_realip_module) HTTP_REALIP=YES ;;
|
||||
@ -441,6 +443,7 @@ cat << END
|
||||
--with-file-aio enable file AIO support
|
||||
|
||||
--with-http_ssl_module enable ngx_http_ssl_module
|
||||
--with-http_quic_module enable ngx_http_quic_module
|
||||
--with-http_v2_module enable ngx_http_v2_module
|
||||
--with-http_v3_module enable ngx_http_v3_module
|
||||
--with-http_realip_module enable ngx_http_realip_module
|
||||
|
@ -1034,9 +1034,11 @@ ngx_close_listening_sockets(ngx_cycle_t *cycle)
|
||||
ls = cycle->listening.elts;
|
||||
for (i = 0; i < cycle->listening.nelts; i++) {
|
||||
|
||||
#if (NGX_QUIC)
|
||||
if (ls[i].quic) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
c = ls[i].connection;
|
||||
|
||||
|
@ -150,9 +150,12 @@ struct ngx_connection_s {
|
||||
|
||||
ngx_proxy_protocol_t *proxy_protocol;
|
||||
|
||||
#if (NGX_SSL || NGX_COMPAT)
|
||||
#if (NGX_QUIC || NGX_COMPAT)
|
||||
ngx_quic_connection_t *quic;
|
||||
ngx_quic_stream_t *qs;
|
||||
#endif
|
||||
|
||||
#if (NGX_SSL || NGX_COMPAT)
|
||||
ngx_ssl_connection_t *ssl;
|
||||
#endif
|
||||
|
||||
|
@ -268,6 +268,8 @@ ngx_process_events_and_timers(ngx_cycle_t *cycle)
|
||||
ngx_int_t
|
||||
ngx_handle_read_event(ngx_event_t *rev, ngx_uint_t flags)
|
||||
{
|
||||
#if (NGX_QUIC)
|
||||
|
||||
ngx_connection_t *c;
|
||||
|
||||
c = rev->data;
|
||||
@ -284,6 +286,8 @@ ngx_handle_read_event(ngx_event_t *rev, ngx_uint_t flags)
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
|
||||
|
||||
/* kqueue, epoll */
|
||||
@ -362,6 +366,8 @@ ngx_handle_write_event(ngx_event_t *wev, size_t lowat)
|
||||
}
|
||||
}
|
||||
|
||||
#if (NGX_QUIC)
|
||||
|
||||
if (c->qs) {
|
||||
|
||||
if (!wev->active && !wev->ready) {
|
||||
@ -374,6 +380,8 @@ ngx_handle_write_event(ngx_event_t *wev, size_t lowat)
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
|
||||
|
||||
/* kqueue, epoll */
|
||||
@ -944,9 +952,11 @@ ngx_send_lowat(ngx_connection_t *c, size_t lowat)
|
||||
{
|
||||
int sndlowat;
|
||||
|
||||
#if (NGX_QUIC)
|
||||
if (c->qs) {
|
||||
return NGX_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (NGX_HAVE_LOWAT_EVENT)
|
||||
|
||||
|
@ -93,6 +93,8 @@ struct ngx_quic_connection_s {
|
||||
ngx_quic_secrets_t next_key;
|
||||
ngx_quic_frames_stream_t crypto[NGX_QUIC_ENCRYPTION_LAST];
|
||||
|
||||
ngx_quic_conf_t *conf;
|
||||
|
||||
ngx_ssl_t *ssl;
|
||||
|
||||
ngx_event_t push;
|
||||
@ -160,7 +162,7 @@ static int ngx_quic_send_alert(ngx_ssl_conn_t *ssl_conn,
|
||||
|
||||
|
||||
static ngx_int_t ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl,
|
||||
ngx_quic_tp_t *tp, ngx_quic_header_t *pkt,
|
||||
ngx_quic_conf_t *conf, ngx_quic_header_t *pkt,
|
||||
ngx_connection_handler_pt handler);
|
||||
static ngx_int_t ngx_quic_new_dcid(ngx_connection_t *c, ngx_str_t *odcid);
|
||||
static ngx_int_t ngx_quic_retry(ngx_connection_t *c);
|
||||
@ -585,7 +587,7 @@ ngx_quic_send_alert(ngx_ssl_conn_t *ssl_conn, enum ssl_encryption_level_t level,
|
||||
|
||||
|
||||
void
|
||||
ngx_quic_run(ngx_connection_t *c, ngx_ssl_t *ssl, ngx_quic_tp_t *tp,
|
||||
ngx_quic_run(ngx_connection_t *c, ngx_ssl_t *ssl, ngx_quic_conf_t *conf,
|
||||
ngx_connection_handler_pt handler)
|
||||
{
|
||||
ngx_buf_t *b;
|
||||
@ -604,7 +606,7 @@ ngx_quic_run(ngx_connection_t *c, ngx_ssl_t *ssl, ngx_quic_tp_t *tp,
|
||||
pkt.data = b->start;
|
||||
pkt.len = b->last - b->start;
|
||||
|
||||
if (ngx_quic_new_connection(c, ssl, tp, &pkt, handler) != NGX_OK) {
|
||||
if (ngx_quic_new_connection(c, ssl, conf, &pkt, handler) != NGX_OK) {
|
||||
ngx_quic_close_connection(c, NGX_ERROR);
|
||||
return;
|
||||
}
|
||||
@ -619,8 +621,9 @@ ngx_quic_run(ngx_connection_t *c, ngx_ssl_t *ssl, ngx_quic_tp_t *tp,
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl, ngx_quic_tp_t *tp,
|
||||
ngx_quic_header_t *pkt, ngx_connection_handler_pt handler)
|
||||
ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl,
|
||||
ngx_quic_conf_t *conf, ngx_quic_header_t *pkt,
|
||||
ngx_connection_handler_pt handler)
|
||||
{
|
||||
ngx_int_t rc;
|
||||
ngx_uint_t i;
|
||||
@ -703,7 +706,8 @@ ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl, ngx_quic_tp_t *tp,
|
||||
|
||||
c->quic = qc;
|
||||
qc->ssl = ssl;
|
||||
qc->tp = *tp;
|
||||
qc->conf = conf;
|
||||
qc->tp = conf->tp;
|
||||
qc->streams.handler = handler;
|
||||
|
||||
ctp = &qc->ctp;
|
||||
@ -767,7 +771,7 @@ ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl, ngx_quic_tp_t *tp,
|
||||
/* NGX_OK */
|
||||
qc->validated = 1;
|
||||
|
||||
} else if (tp->retry) {
|
||||
} else if (conf->retry) {
|
||||
return ngx_quic_retry(c);
|
||||
}
|
||||
|
||||
@ -949,7 +953,7 @@ ngx_quic_new_token(ngx_connection_t *c, ngx_str_t *token)
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
key = c->quic->tp.token_key;
|
||||
key = c->quic->conf->token_key;
|
||||
iv = token->data;
|
||||
|
||||
if (RAND_bytes(iv, iv_len) <= 0
|
||||
@ -1023,7 +1027,7 @@ ngx_quic_validate_token(ngx_connection_t *c, ngx_quic_header_t *pkt)
|
||||
/* NEW_TOKEN in a previous connection */
|
||||
|
||||
cipher = EVP_aes_256_cbc();
|
||||
key = c->quic->tp.token_key;
|
||||
key = c->quic->conf->token_key;
|
||||
iv = pkt->token.data;
|
||||
iv_len = EVP_CIPHER_iv_length(cipher);
|
||||
|
||||
@ -2237,7 +2241,7 @@ ngx_quic_send_new_token(ngx_connection_t *c)
|
||||
ngx_str_t token;
|
||||
ngx_quic_frame_t *frame;
|
||||
|
||||
if (!c->quic->tp.retry) {
|
||||
if (!c->quic->conf->retry) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
@ -78,15 +78,19 @@ typedef struct {
|
||||
ngx_str_t initial_scid;
|
||||
ngx_str_t retry_scid;
|
||||
|
||||
ngx_flag_t retry;
|
||||
u_char token_key[32]; /* AES 256 */
|
||||
|
||||
/* TODO */
|
||||
u_char stateless_reset_token[16];
|
||||
void *preferred_address;
|
||||
} ngx_quic_tp_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_quic_tp_t tp;
|
||||
ngx_flag_t retry;
|
||||
u_char token_key[32]; /* AES 256 */
|
||||
} ngx_quic_conf_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint64_t sent;
|
||||
uint64_t received;
|
||||
@ -107,7 +111,7 @@ struct ngx_quic_stream_s {
|
||||
};
|
||||
|
||||
|
||||
void ngx_quic_run(ngx_connection_t *c, ngx_ssl_t *ssl, ngx_quic_tp_t *tp,
|
||||
void ngx_quic_run(ngx_connection_t *c, ngx_ssl_t *ssl, ngx_quic_conf_t *conf,
|
||||
ngx_connection_handler_pt handler);
|
||||
ngx_connection_t *ngx_quic_create_uni_stream(ngx_connection_t *c);
|
||||
void ngx_quic_finalize_connection(ngx_connection_t *c, ngx_uint_t err,
|
||||
|
344
src/http/modules/ngx_http_quic_module.c
Normal file
344
src/http/modules/ngx_http_quic_module.c
Normal file
@ -0,0 +1,344 @@
|
||||
|
||||
/*
|
||||
* Copyright (C) Nginx, Inc.
|
||||
* Copyright (C) Roman Arutyunyan
|
||||
*/
|
||||
|
||||
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
#include <ngx_http.h>
|
||||
|
||||
|
||||
static ngx_int_t ngx_http_variable_quic(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_quic_add_variables(ngx_conf_t *cf);
|
||||
static void *ngx_http_quic_create_srv_conf(ngx_conf_t *cf);
|
||||
static char *ngx_http_quic_merge_srv_conf(ngx_conf_t *cf, void *parent,
|
||||
void *child);
|
||||
static char *ngx_http_quic_max_ack_delay(ngx_conf_t *cf, void *post,
|
||||
void *data);
|
||||
static char *ngx_http_quic_max_udp_payload_size(ngx_conf_t *cf, void *post,
|
||||
void *data);
|
||||
|
||||
|
||||
static ngx_conf_post_t ngx_http_quic_max_ack_delay_post =
|
||||
{ ngx_http_quic_max_ack_delay };
|
||||
static ngx_conf_post_t ngx_http_quic_max_udp_payload_size_post =
|
||||
{ ngx_http_quic_max_udp_payload_size };
|
||||
static ngx_conf_num_bounds_t ngx_http_quic_ack_delay_exponent_bounds =
|
||||
{ ngx_conf_check_num_bounds, 0, 20 };
|
||||
static ngx_conf_num_bounds_t ngx_http_quic_active_connection_id_limit_bounds =
|
||||
{ ngx_conf_check_num_bounds, 2, -1 };
|
||||
|
||||
|
||||
static ngx_command_t ngx_http_quic_commands[] = {
|
||||
|
||||
{ ngx_string("quic_max_idle_timeout"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_msec_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_quic_conf_t, tp.max_idle_timeout),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("quic_max_ack_delay"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_msec_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_quic_conf_t, tp.max_ack_delay),
|
||||
&ngx_http_quic_max_ack_delay_post },
|
||||
|
||||
{ ngx_string("quic_max_udp_payload_size"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_size_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_quic_conf_t, tp.max_udp_payload_size),
|
||||
&ngx_http_quic_max_udp_payload_size_post },
|
||||
|
||||
{ ngx_string("quic_initial_max_data"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_size_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_quic_conf_t, tp.initial_max_data),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("quic_initial_max_stream_data_bidi_local"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_size_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_quic_conf_t, tp.initial_max_stream_data_bidi_local),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("quic_initial_max_stream_data_bidi_remote"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_size_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_quic_conf_t, tp.initial_max_stream_data_bidi_remote),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("quic_initial_max_stream_data_uni"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_size_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_quic_conf_t, tp.initial_max_stream_data_uni),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("quic_initial_max_streams_bidi"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_num_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_quic_conf_t, tp.initial_max_streams_bidi),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("quic_initial_max_streams_uni"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_num_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_quic_conf_t, tp.initial_max_streams_uni),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("quic_ack_delay_exponent"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_num_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_quic_conf_t, tp.ack_delay_exponent),
|
||||
&ngx_http_quic_ack_delay_exponent_bounds },
|
||||
|
||||
{ ngx_string("quic_active_migration"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_num_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_quic_conf_t, tp.disable_active_migration),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("quic_active_connection_id_limit"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_num_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_quic_conf_t, tp.active_connection_id_limit),
|
||||
&ngx_http_quic_active_connection_id_limit_bounds },
|
||||
|
||||
{ ngx_string("quic_retry"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
|
||||
ngx_conf_set_flag_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_quic_conf_t, retry),
|
||||
NULL },
|
||||
|
||||
ngx_null_command
|
||||
};
|
||||
|
||||
|
||||
static ngx_http_module_t ngx_http_quic_module_ctx = {
|
||||
ngx_http_quic_add_variables, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
NULL, /* create main configuration */
|
||||
NULL, /* init main configuration */
|
||||
|
||||
ngx_http_quic_create_srv_conf, /* create server configuration */
|
||||
ngx_http_quic_merge_srv_conf, /* merge server configuration */
|
||||
|
||||
NULL, /* create location configuration */
|
||||
NULL /* merge location configuration */
|
||||
};
|
||||
|
||||
|
||||
ngx_module_t ngx_http_quic_module = {
|
||||
NGX_MODULE_V1,
|
||||
&ngx_http_quic_module_ctx, /* module context */
|
||||
ngx_http_quic_commands, /* module directives */
|
||||
NGX_HTTP_MODULE, /* module type */
|
||||
NULL, /* init master */
|
||||
NULL, /* init module */
|
||||
NULL, /* init process */
|
||||
NULL, /* init thread */
|
||||
NULL, /* exit thread */
|
||||
NULL, /* exit process */
|
||||
NULL, /* exit master */
|
||||
NGX_MODULE_V1_PADDING
|
||||
};
|
||||
|
||||
|
||||
static ngx_http_variable_t ngx_http_quic_vars[] = {
|
||||
|
||||
{ ngx_string("quic"), NULL, ngx_http_variable_quic, 0, 0, 0 },
|
||||
|
||||
ngx_http_null_variable
|
||||
};
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_variable_quic(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
{
|
||||
if (r->connection->qs) {
|
||||
|
||||
v->len = 4;
|
||||
v->valid = 1;
|
||||
v->no_cacheable = 1;
|
||||
v->not_found = 0;
|
||||
v->data = (u_char *) "quic";
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
v->not_found = 1;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_quic_add_variables(ngx_conf_t *cf)
|
||||
{
|
||||
ngx_http_variable_t *var, *v;
|
||||
|
||||
for (v = ngx_http_quic_vars; v->name.len; v++) {
|
||||
var = ngx_http_add_variable(cf, &v->name, v->flags);
|
||||
if (var == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
var->get_handler = v->get_handler;
|
||||
var->data = v->data;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ngx_http_quic_create_srv_conf(ngx_conf_t *cf)
|
||||
{
|
||||
ngx_quic_conf_t *conf;
|
||||
|
||||
conf = ngx_pcalloc(cf->pool, sizeof(ngx_quic_conf_t));
|
||||
if (conf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* set by ngx_pcalloc():
|
||||
*
|
||||
* conf->tp.original_dcid = { 0, NULL };
|
||||
* conf->tp.initial_scid = { 0, NULL };
|
||||
* conf->tp.retry_scid = { 0, NULL };
|
||||
* conf->tp.stateless_reset_token = { 0 }
|
||||
* conf->tp.preferred_address = NULL
|
||||
*/
|
||||
|
||||
conf->tp.max_idle_timeout = NGX_CONF_UNSET_MSEC;
|
||||
conf->tp.max_ack_delay = NGX_CONF_UNSET_MSEC;
|
||||
conf->tp.max_udp_payload_size = NGX_CONF_UNSET_SIZE;
|
||||
conf->tp.initial_max_data = NGX_CONF_UNSET_SIZE;
|
||||
conf->tp.initial_max_stream_data_bidi_local = NGX_CONF_UNSET_SIZE;
|
||||
conf->tp.initial_max_stream_data_bidi_remote = NGX_CONF_UNSET_SIZE;
|
||||
conf->tp.initial_max_stream_data_uni = NGX_CONF_UNSET_SIZE;
|
||||
conf->tp.initial_max_streams_bidi = NGX_CONF_UNSET_UINT;
|
||||
conf->tp.initial_max_streams_uni = NGX_CONF_UNSET_UINT;
|
||||
conf->tp.ack_delay_exponent = NGX_CONF_UNSET_UINT;
|
||||
conf->tp.disable_active_migration = NGX_CONF_UNSET_UINT;
|
||||
conf->tp.active_connection_id_limit = NGX_CONF_UNSET_UINT;
|
||||
|
||||
conf->retry = NGX_CONF_UNSET;
|
||||
|
||||
return conf;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_quic_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
{
|
||||
ngx_quic_conf_t *prev = parent;
|
||||
ngx_quic_conf_t *conf = child;
|
||||
|
||||
ngx_conf_merge_msec_value(conf->tp.max_idle_timeout,
|
||||
prev->tp.max_idle_timeout, 60000);
|
||||
|
||||
ngx_conf_merge_msec_value(conf->tp.max_ack_delay,
|
||||
prev->tp.max_ack_delay,
|
||||
NGX_QUIC_DEFAULT_MAX_ACK_DELAY);
|
||||
|
||||
ngx_conf_merge_size_value(conf->tp.max_udp_payload_size,
|
||||
prev->tp.max_udp_payload_size,
|
||||
NGX_QUIC_MAX_UDP_PAYLOAD_SIZE);
|
||||
|
||||
ngx_conf_merge_size_value(conf->tp.initial_max_data,
|
||||
prev->tp.initial_max_data,
|
||||
16 * NGX_QUIC_STREAM_BUFSIZE);
|
||||
|
||||
ngx_conf_merge_size_value(conf->tp.initial_max_stream_data_bidi_local,
|
||||
prev->tp.initial_max_stream_data_bidi_local,
|
||||
NGX_QUIC_STREAM_BUFSIZE);
|
||||
|
||||
ngx_conf_merge_size_value(conf->tp.initial_max_stream_data_bidi_remote,
|
||||
prev->tp.initial_max_stream_data_bidi_remote,
|
||||
NGX_QUIC_STREAM_BUFSIZE);
|
||||
|
||||
ngx_conf_merge_size_value(conf->tp.initial_max_stream_data_uni,
|
||||
prev->tp.initial_max_stream_data_uni,
|
||||
NGX_QUIC_STREAM_BUFSIZE);
|
||||
|
||||
ngx_conf_merge_uint_value(conf->tp.initial_max_streams_bidi,
|
||||
prev->tp.initial_max_streams_bidi, 16);
|
||||
|
||||
ngx_conf_merge_uint_value(conf->tp.initial_max_streams_uni,
|
||||
prev->tp.initial_max_streams_uni, 16);
|
||||
|
||||
ngx_conf_merge_uint_value(conf->tp.ack_delay_exponent,
|
||||
prev->tp.ack_delay_exponent,
|
||||
NGX_QUIC_DEFAULT_ACK_DELAY_EXPONENT);
|
||||
|
||||
ngx_conf_merge_uint_value(conf->tp.disable_active_migration,
|
||||
prev->tp.disable_active_migration, 1);
|
||||
|
||||
ngx_conf_merge_uint_value(conf->tp.active_connection_id_limit,
|
||||
prev->tp.active_connection_id_limit, 2);
|
||||
|
||||
ngx_conf_merge_value(conf->retry, prev->retry, 0);
|
||||
|
||||
if (conf->retry) {
|
||||
if (RAND_bytes(conf->token_key, sizeof(conf->token_key)) <= 0) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_quic_max_ack_delay(ngx_conf_t *cf, void *post, void *data)
|
||||
{
|
||||
ngx_msec_t *sp = data;
|
||||
|
||||
if (*sp > 16384) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"\"quic_max_ack_delay\" must be less than 16384");
|
||||
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_quic_max_udp_payload_size(ngx_conf_t *cf, void *post, void *data)
|
||||
{
|
||||
size_t *sp = data;
|
||||
|
||||
if (*sp < NGX_QUIC_MIN_INITIAL_SIZE
|
||||
|| *sp > NGX_QUIC_MAX_UDP_PAYLOAD_SIZE)
|
||||
{
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"\"quic_max_udp_payload_size\" must be between "
|
||||
"%d and %d",
|
||||
NGX_QUIC_MIN_INITIAL_SIZE,
|
||||
NGX_QUIC_MAX_UDP_PAYLOAD_SIZE);
|
||||
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
25
src/http/modules/ngx_http_quic_module.h
Normal file
25
src/http/modules/ngx_http_quic_module.h
Normal file
@ -0,0 +1,25 @@
|
||||
|
||||
/*
|
||||
* Copyright (C) Nginx, Inc.
|
||||
* Copyright (C) Roman Arutyunyan
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _NGX_HTTP_QUIC_H_INCLUDED_
|
||||
#define _NGX_HTTP_QUIC_H_INCLUDED_
|
||||
|
||||
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
#include <ngx_http.h>
|
||||
|
||||
|
||||
#define NGX_HTTP_QUIC_ALPN(s) NGX_HTTP_QUIC_ALPN_DRAFT(s)
|
||||
#define NGX_HTTP_QUIC_ALPN_DRAFT(s) "\x05hq-" #s
|
||||
#define NGX_HTTP_QUIC_ALPN_ADVERTISE NGX_HTTP_QUIC_ALPN(NGX_QUIC_DRAFT_VERSION)
|
||||
|
||||
|
||||
extern ngx_module_t ngx_http_quic_module;
|
||||
|
||||
|
||||
#endif /* _NGX_HTTP_QUIC_H_INCLUDED_ */
|
@ -402,7 +402,7 @@ ngx_http_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn, const unsigned char **out,
|
||||
#if (NGX_DEBUG)
|
||||
unsigned int i;
|
||||
#endif
|
||||
#if (NGX_HTTP_V2 || NGX_HTTP_V3)
|
||||
#if (NGX_HTTP_V2 || NGX_HTTP_QUIC)
|
||||
ngx_http_connection_t *hc;
|
||||
#endif
|
||||
#if (NGX_HTTP_V2 || NGX_DEBUG)
|
||||
@ -419,7 +419,7 @@ ngx_http_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn, const unsigned char **out,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (NGX_HTTP_V2 || NGX_HTTP_V3)
|
||||
#if (NGX_HTTP_V2 || NGX_HTTP_QUIC)
|
||||
hc = c->data;
|
||||
#endif
|
||||
|
||||
@ -436,6 +436,12 @@ ngx_http_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn, const unsigned char **out,
|
||||
srv = (unsigned char *) NGX_HTTP_V3_ALPN_ADVERTISE;
|
||||
srvlen = sizeof(NGX_HTTP_V3_ALPN_ADVERTISE) - 1;
|
||||
} else
|
||||
#endif
|
||||
#if (NGX_HTTP_QUIC)
|
||||
if (hc->addr_conf->quic) {
|
||||
srv = (unsigned char *) NGX_HTTP_QUIC_ALPN_ADVERTISE;
|
||||
srvlen = sizeof(NGX_HTTP_QUIC_ALPN_ADVERTISE) - 1;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
srv = (unsigned char *) NGX_HTTP_NPN_ADVERTISE;
|
||||
@ -1247,6 +1253,7 @@ static ngx_int_t
|
||||
ngx_http_ssl_init(ngx_conf_t *cf)
|
||||
{
|
||||
ngx_uint_t a, p, s;
|
||||
const char *name;
|
||||
ngx_http_conf_addr_t *addr;
|
||||
ngx_http_conf_port_t *port;
|
||||
ngx_http_ssl_srv_conf_t *sscf;
|
||||
@ -1296,26 +1303,36 @@ ngx_http_ssl_init(ngx_conf_t *cf)
|
||||
addr = port[p].addrs.elts;
|
||||
for (a = 0; a < port[p].addrs.nelts; a++) {
|
||||
|
||||
if (!addr[a].opt.ssl && !addr[a].opt.http3) {
|
||||
if (!addr[a].opt.ssl && !addr[a].opt.quic) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (addr[a].opt.http3) {
|
||||
name = "http3";
|
||||
|
||||
} else if (addr[a].opt.quic) {
|
||||
name = "quic";
|
||||
|
||||
} else {
|
||||
name = "ssl";
|
||||
}
|
||||
|
||||
cscf = addr[a].default_server;
|
||||
sscf = cscf->ctx->srv_conf[ngx_http_ssl_module.ctx_index];
|
||||
|
||||
if (sscf->certificates == NULL) {
|
||||
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
|
||||
"no \"ssl_certificate\" is defined for "
|
||||
"the \"listen ... ssl\" directive in %s:%ui",
|
||||
cscf->file_name, cscf->line);
|
||||
"the \"listen ... %s\" directive in %s:%ui",
|
||||
name, cscf->file_name, cscf->line);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (addr[a].opt.http3 && !(sscf->protocols & NGX_SSL_TLSv1_3)) {
|
||||
if (addr[a].opt.quic && !(sscf->protocols & NGX_SSL_TLSv1_3)) {
|
||||
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
|
||||
"\"ssl_protocols\" did not enable TLSv1.3 for "
|
||||
"the \"listen ... http3\" directive in %s:%ui",
|
||||
cscf->file_name, cscf->line);
|
||||
"the \"listen ... %s\" directives in %s:%ui",
|
||||
name, cscf->file_name, cscf->line);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
@ -1200,10 +1200,13 @@ ngx_http_add_addresses(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
|
||||
#if (NGX_HTTP_SSL)
|
||||
ngx_uint_t ssl;
|
||||
#endif
|
||||
#if (NGX_HTTP_QUIC)
|
||||
ngx_uint_t quic;
|
||||
#endif
|
||||
#if (NGX_HTTP_V2)
|
||||
ngx_uint_t http2;
|
||||
#endif
|
||||
#if (NGX_HTTP_SSL)
|
||||
#if (NGX_HTTP_V3)
|
||||
ngx_uint_t http3;
|
||||
#endif
|
||||
|
||||
@ -1238,10 +1241,13 @@ ngx_http_add_addresses(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
|
||||
#if (NGX_HTTP_SSL)
|
||||
ssl = lsopt->ssl || addr[i].opt.ssl;
|
||||
#endif
|
||||
#if (NGX_HTTP_QUIC)
|
||||
quic = lsopt->quic || addr[i].opt.quic;
|
||||
#endif
|
||||
#if (NGX_HTTP_V2)
|
||||
http2 = lsopt->http2 || addr[i].opt.http2;
|
||||
#endif
|
||||
#if (NGX_HTTP_SSL)
|
||||
#if (NGX_HTTP_V3)
|
||||
http3 = lsopt->http3 || addr[i].opt.http3;
|
||||
#endif
|
||||
|
||||
@ -1277,10 +1283,13 @@ ngx_http_add_addresses(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
|
||||
#if (NGX_HTTP_SSL)
|
||||
addr[i].opt.ssl = ssl;
|
||||
#endif
|
||||
#if (NGX_HTTP_QUIC)
|
||||
addr[i].opt.quic = quic;
|
||||
#endif
|
||||
#if (NGX_HTTP_V2)
|
||||
addr[i].opt.http2 = http2;
|
||||
#endif
|
||||
#if (NGX_HTTP_SSL)
|
||||
#if (NGX_HTTP_V3)
|
||||
addr[i].opt.http3 = http3;
|
||||
#endif
|
||||
|
||||
@ -1326,12 +1335,12 @@ ngx_http_add_address(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
|
||||
|
||||
#endif
|
||||
|
||||
#if (NGX_HTTP_SSL && !defined NGX_OPENSSL_QUIC)
|
||||
#if (NGX_HTTP_QUIC && !defined NGX_OPENSSL_QUIC)
|
||||
|
||||
if (lsopt->http3) {
|
||||
if (lsopt->quic) {
|
||||
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||
"nginx was built with OpenSSL that lacks QUIC "
|
||||
"support, HTTP/3 is not enabled for %V",
|
||||
"support, QUIC is not enabled for %V",
|
||||
&lsopt->addr_text);
|
||||
}
|
||||
|
||||
@ -1797,8 +1806,8 @@ ngx_http_add_listening(ngx_conf_t *cf, ngx_http_conf_addr_t *addr)
|
||||
|
||||
ls->wildcard = addr->opt.wildcard;
|
||||
|
||||
#if (NGX_HTTP_SSL)
|
||||
ls->quic = addr->opt.http3;
|
||||
#if (NGX_HTTP_QUIC)
|
||||
ls->quic = addr->opt.quic;
|
||||
#endif
|
||||
|
||||
return ls;
|
||||
@ -1830,10 +1839,13 @@ ngx_http_add_addrs(ngx_conf_t *cf, ngx_http_port_t *hport,
|
||||
#if (NGX_HTTP_SSL)
|
||||
addrs[i].conf.ssl = addr[i].opt.ssl;
|
||||
#endif
|
||||
#if (NGX_HTTP_QUIC)
|
||||
addrs[i].conf.quic = addr[i].opt.quic;
|
||||
#endif
|
||||
#if (NGX_HTTP_V2)
|
||||
addrs[i].conf.http2 = addr[i].opt.http2;
|
||||
#endif
|
||||
#if (NGX_HTTP_SSL)
|
||||
#if (NGX_HTTP_V3)
|
||||
addrs[i].conf.http3 = addr[i].opt.http3;
|
||||
#endif
|
||||
addrs[i].conf.proxy_protocol = addr[i].opt.proxy_protocol;
|
||||
@ -1898,10 +1910,13 @@ ngx_http_add_addrs6(ngx_conf_t *cf, ngx_http_port_t *hport,
|
||||
#if (NGX_HTTP_SSL)
|
||||
addrs6[i].conf.ssl = addr[i].opt.ssl;
|
||||
#endif
|
||||
#if (NGX_HTTP_QUIC)
|
||||
addrs6[i].conf.quic = addr[i].opt.quic;
|
||||
#endif
|
||||
#if (NGX_HTTP_V2)
|
||||
addrs6[i].conf.http2 = addr[i].opt.http2;
|
||||
#endif
|
||||
#if (NGX_HTTP_SSL)
|
||||
#if (NGX_HTTP_V3)
|
||||
addrs6[i].conf.http3 = addr[i].opt.http3;
|
||||
#endif
|
||||
addrs6[i].conf.proxy_protocol = addr[i].opt.proxy_protocol;
|
||||
|
@ -50,6 +50,9 @@ typedef u_char *(*ngx_http_log_handler_pt)(ngx_http_request_t *r,
|
||||
#if (NGX_HTTP_SSL)
|
||||
#include <ngx_http_ssl_module.h>
|
||||
#endif
|
||||
#if (NGX_HTTP_QUIC)
|
||||
#include <ngx_http_quic_module.h>
|
||||
#endif
|
||||
|
||||
|
||||
struct ngx_http_log_ctx_s {
|
||||
|
@ -4079,8 +4079,22 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ngx_strcmp(value[n].data, "quic") == 0) {
|
||||
#if (NGX_HTTP_QUIC)
|
||||
lsopt.quic = 1;
|
||||
lsopt.type = SOCK_DGRAM;
|
||||
continue;
|
||||
#else
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"the \"quic\" parameter requires "
|
||||
"ngx_http_quic_module");
|
||||
return NGX_CONF_ERROR;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ngx_strcmp(value[n].data, "http3") == 0) {
|
||||
#if (NGX_HTTP_V3)
|
||||
lsopt.quic = 1;
|
||||
lsopt.http3 = 1;
|
||||
lsopt.type = SOCK_DGRAM;
|
||||
continue;
|
||||
@ -4201,6 +4215,22 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
#if (NGX_HTTP_SSL)
|
||||
|
||||
#if (NGX_HTTP_V3)
|
||||
if (lsopt.ssl && lsopt.http3) {
|
||||
return "\"ssl\" parameter is incompatible with \"http3\"";
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (NGX_HTTP_QUIC)
|
||||
if (lsopt.ssl && lsopt.quic) {
|
||||
return "\"ssl\" parameter is incompatible with \"quic\"";
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
for (n = 0; n < u.naddrs; n++) {
|
||||
lsopt.sockaddr = u.addrs[n].sockaddr;
|
||||
lsopt.socklen = u.addrs[n].socklen;
|
||||
|
@ -74,6 +74,7 @@ typedef struct {
|
||||
unsigned bind:1;
|
||||
unsigned wildcard:1;
|
||||
unsigned ssl:1;
|
||||
unsigned quic:1;
|
||||
unsigned http2:1;
|
||||
unsigned http3:1;
|
||||
#if (NGX_HAVE_INET6)
|
||||
@ -238,6 +239,7 @@ struct ngx_http_addr_conf_s {
|
||||
ngx_http_virtual_names_t *virtual_names;
|
||||
|
||||
unsigned ssl:1;
|
||||
unsigned quic:1;
|
||||
unsigned http2:1;
|
||||
unsigned http3:1;
|
||||
unsigned proxy_protocol:1;
|
||||
|
@ -64,9 +64,6 @@ static void ngx_http_ssl_handshake(ngx_event_t *rev);
|
||||
static void ngx_http_ssl_handshake_handler(ngx_connection_t *c);
|
||||
#endif
|
||||
|
||||
#if (NGX_HTTP_V3)
|
||||
static void ngx_http_quic_stream_handler(ngx_connection_t *c);
|
||||
#endif
|
||||
|
||||
static char *ngx_http_client_errors[] = {
|
||||
|
||||
@ -221,26 +218,7 @@ ngx_http_init_connection(ngx_connection_t *c)
|
||||
ngx_http_in6_addr_t *addr6;
|
||||
#endif
|
||||
|
||||
#if (NGX_HTTP_V3)
|
||||
if (c->type == SOCK_DGRAM) {
|
||||
ngx_http_v3_connection_t *h3c;
|
||||
|
||||
h3c = ngx_pcalloc(c->pool, sizeof(ngx_http_v3_connection_t));
|
||||
if (h3c == NULL) {
|
||||
ngx_http_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_queue_init(&h3c->blocked);
|
||||
|
||||
hc = &h3c->hc;
|
||||
hc->quic = 1;
|
||||
hc->ssl = 1;
|
||||
|
||||
} else
|
||||
#endif
|
||||
hc = ngx_pcalloc(c->pool, sizeof(ngx_http_connection_t));
|
||||
|
||||
hc = ngx_pcalloc(c->pool, sizeof(ngx_http_connection_t));
|
||||
if (hc == NULL) {
|
||||
ngx_http_close_connection(c);
|
||||
return;
|
||||
@ -325,6 +303,46 @@ ngx_http_init_connection(ngx_connection_t *c)
|
||||
/* the default server configuration for the address:port */
|
||||
hc->conf_ctx = hc->addr_conf->default_server->ctx;
|
||||
|
||||
#if (NGX_HTTP_QUIC)
|
||||
|
||||
if (hc->addr_conf->quic) {
|
||||
ngx_quic_conf_t *qcf;
|
||||
ngx_http_ssl_srv_conf_t *sscf;
|
||||
|
||||
#if (NGX_HTTP_V3)
|
||||
|
||||
if (hc->addr_conf->http3) {
|
||||
ngx_int_t rc;
|
||||
|
||||
rc = ngx_http_v3_init_connection(c);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
ngx_http_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rc == NGX_DONE) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (c->qs == NULL) {
|
||||
c->log->connection = c->number;
|
||||
|
||||
qcf = ngx_http_get_module_srv_conf(hc->conf_ctx,
|
||||
ngx_http_quic_module);
|
||||
sscf = ngx_http_get_module_srv_conf(hc->conf_ctx,
|
||||
ngx_http_ssl_module);
|
||||
|
||||
ngx_quic_run(c, &sscf->ssl, qcf, ngx_http_init_connection);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
ctx = ngx_palloc(c->pool, sizeof(ngx_http_log_ctx_t));
|
||||
if (ctx == NULL) {
|
||||
ngx_http_close_connection(c);
|
||||
@ -346,23 +364,6 @@ ngx_http_init_connection(ngx_connection_t *c)
|
||||
rev->handler = ngx_http_wait_request_handler;
|
||||
c->write->handler = ngx_http_empty_handler;
|
||||
|
||||
if (c->shared) {
|
||||
rev->ready = 1;
|
||||
}
|
||||
|
||||
#if (NGX_HTTP_V3)
|
||||
if (hc->quic) {
|
||||
ngx_http_v3_srv_conf_t *v3cf;
|
||||
ngx_http_ssl_srv_conf_t *sscf;
|
||||
|
||||
v3cf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_v3_module);
|
||||
sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_ssl_module);
|
||||
|
||||
ngx_quic_run(c, &sscf->ssl, &v3cf->quic, ngx_http_quic_stream_handler);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (NGX_HTTP_V2)
|
||||
if (hc->addr_conf->http2) {
|
||||
rev->handler = ngx_http_v2_init;
|
||||
@ -410,72 +411,6 @@ ngx_http_init_connection(ngx_connection_t *c)
|
||||
}
|
||||
|
||||
|
||||
#if (NGX_HTTP_V3)
|
||||
|
||||
static void
|
||||
ngx_http_quic_stream_handler(ngx_connection_t *c)
|
||||
{
|
||||
ngx_event_t *rev;
|
||||
ngx_http_log_ctx_t *ctx;
|
||||
ngx_http_connection_t *hc;
|
||||
ngx_http_v3_connection_t *h3c;
|
||||
|
||||
h3c = c->qs->parent->data;
|
||||
|
||||
if (!h3c->settings_sent) {
|
||||
h3c->settings_sent = 1;
|
||||
|
||||
if (ngx_http_v3_send_settings(c) != NGX_OK) {
|
||||
ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_INTERNAL_ERROR,
|
||||
"could not send settings");
|
||||
ngx_http_close_connection(c);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (c->qs->id & NGX_QUIC_STREAM_UNIDIRECTIONAL) {
|
||||
ngx_http_v3_handle_client_uni_stream(c);
|
||||
return;
|
||||
}
|
||||
|
||||
hc = ngx_pcalloc(c->pool, sizeof(ngx_http_connection_t));
|
||||
if (hc == NULL) {
|
||||
ngx_http_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_memcpy(hc, h3c, sizeof(ngx_http_connection_t));
|
||||
c->data = hc;
|
||||
|
||||
ctx = ngx_palloc(c->pool, sizeof(ngx_http_log_ctx_t));
|
||||
if (ctx == NULL) {
|
||||
ngx_http_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
ctx->connection = c;
|
||||
ctx->request = NULL;
|
||||
ctx->current_request = NULL;
|
||||
|
||||
c->log->handler = ngx_http_log_error;
|
||||
c->log->data = ctx;
|
||||
c->log->action = "waiting for request";
|
||||
|
||||
c->log_error = NGX_ERROR_INFO;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||
"http3 new stream id:0x%uXL", c->qs->id);
|
||||
|
||||
rev = c->read;
|
||||
rev->handler = ngx_http_wait_request_handler;
|
||||
c->write->handler = ngx_http_empty_handler;
|
||||
|
||||
rev->handler(rev);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
ngx_http_wait_request_handler(ngx_event_t *rev)
|
||||
{
|
||||
@ -725,7 +660,7 @@ ngx_http_alloc_request(ngx_connection_t *c)
|
||||
r->http_version = NGX_HTTP_VERSION_10;
|
||||
|
||||
#if (NGX_HTTP_V3)
|
||||
if (hc->quic) {
|
||||
if (hc->addr_conf->http3) {
|
||||
r->http_version = NGX_HTTP_VERSION_30;
|
||||
}
|
||||
#endif
|
||||
|
@ -324,7 +324,6 @@ typedef struct {
|
||||
ngx_chain_t *free;
|
||||
|
||||
unsigned ssl:1;
|
||||
unsigned quic:1;
|
||||
unsigned proxy_protocol:1;
|
||||
} ngx_http_connection_t;
|
||||
|
||||
|
@ -118,6 +118,8 @@ typedef struct {
|
||||
} ngx_http_v3_connection_t;
|
||||
|
||||
|
||||
ngx_int_t ngx_http_v3_init_connection(ngx_connection_t *c);
|
||||
|
||||
ngx_int_t ngx_http_v3_parse_request(ngx_http_request_t *r, ngx_buf_t *b);
|
||||
ngx_int_t ngx_http_v3_parse_header(ngx_http_request_t *r, ngx_buf_t *b,
|
||||
ngx_uint_t allow_underscores);
|
||||
@ -130,9 +132,6 @@ uintptr_t ngx_http_v3_encode_varlen_int(u_char *p, uint64_t value);
|
||||
uintptr_t ngx_http_v3_encode_prefix_int(u_char *p, uint64_t value,
|
||||
ngx_uint_t prefix);
|
||||
|
||||
ngx_int_t ngx_http_v3_send_settings(ngx_connection_t *c);
|
||||
void ngx_http_v3_handle_client_uni_stream(ngx_connection_t *c);
|
||||
|
||||
ngx_int_t ngx_http_v3_ref_insert(ngx_connection_t *c, ngx_uint_t dynamic,
|
||||
ngx_uint_t index, ngx_str_t *value);
|
||||
ngx_int_t ngx_http_v3_insert(ngx_connection_t *c, ngx_str_t *name,
|
||||
|
@ -10,114 +10,8 @@
|
||||
#include <ngx_http.h>
|
||||
|
||||
|
||||
static char *ngx_http_v3_max_ack_delay(ngx_conf_t *cf, void *post, void *data);
|
||||
static char *ngx_http_v3_max_udp_payload_size(ngx_conf_t *cf, void *post,
|
||||
void *data);
|
||||
|
||||
|
||||
static ngx_conf_post_t ngx_http_v3_max_ack_delay_post =
|
||||
{ ngx_http_v3_max_ack_delay };
|
||||
static ngx_conf_post_t ngx_http_v3_max_udp_payload_size_post =
|
||||
{ ngx_http_v3_max_udp_payload_size };
|
||||
static ngx_conf_num_bounds_t ngx_http_v3_ack_delay_exponent_bounds =
|
||||
{ ngx_conf_check_num_bounds, 0, 20 };
|
||||
static ngx_conf_num_bounds_t ngx_http_v3_active_connection_id_limit_bounds =
|
||||
{ ngx_conf_check_num_bounds, 2, -1 };
|
||||
|
||||
|
||||
static ngx_command_t ngx_http_v3_commands[] = {
|
||||
|
||||
{ ngx_string("quic_max_idle_timeout"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_msec_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_http_v3_srv_conf_t, quic.max_idle_timeout),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("quic_max_ack_delay"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_msec_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_http_v3_srv_conf_t, quic.max_ack_delay),
|
||||
&ngx_http_v3_max_ack_delay_post },
|
||||
|
||||
{ ngx_string("quic_max_udp_payload_size"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_size_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_http_v3_srv_conf_t, quic.max_udp_payload_size),
|
||||
&ngx_http_v3_max_udp_payload_size_post },
|
||||
|
||||
{ ngx_string("quic_initial_max_data"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_size_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_http_v3_srv_conf_t, quic.initial_max_data),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("quic_initial_max_stream_data_bidi_local"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_size_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_http_v3_srv_conf_t, quic.initial_max_stream_data_bidi_local),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("quic_initial_max_stream_data_bidi_remote"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_size_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_http_v3_srv_conf_t, quic.initial_max_stream_data_bidi_remote),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("quic_initial_max_stream_data_uni"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_size_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_http_v3_srv_conf_t, quic.initial_max_stream_data_uni),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("quic_initial_max_streams_bidi"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_num_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_http_v3_srv_conf_t, quic.initial_max_streams_bidi),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("quic_initial_max_streams_uni"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_num_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_http_v3_srv_conf_t, quic.initial_max_streams_uni),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("quic_ack_delay_exponent"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_num_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_http_v3_srv_conf_t, quic.ack_delay_exponent),
|
||||
&ngx_http_v3_ack_delay_exponent_bounds },
|
||||
|
||||
{ ngx_string("quic_active_migration"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_num_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_http_v3_srv_conf_t, quic.disable_active_migration),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("quic_active_connection_id_limit"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_num_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_http_v3_srv_conf_t, quic.active_connection_id_limit),
|
||||
&ngx_http_v3_active_connection_id_limit_bounds },
|
||||
|
||||
{ ngx_string("quic_retry"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
|
||||
ngx_conf_set_flag_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_http_v3_srv_conf_t, quic.retry),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("http3_max_field_size"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_size_slot,
|
||||
@ -143,8 +37,6 @@ static ngx_command_t ngx_http_v3_commands[] = {
|
||||
};
|
||||
|
||||
|
||||
static ngx_int_t ngx_http_variable_quic(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_variable_http3(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_v3_add_variables(ngx_conf_t *cf);
|
||||
@ -185,8 +77,6 @@ ngx_module_t ngx_http_v3_module = {
|
||||
|
||||
|
||||
static ngx_http_variable_t ngx_http_v3_vars[] = {
|
||||
{ ngx_string("quic"), NULL, ngx_http_variable_quic,
|
||||
0, 0, 0 },
|
||||
|
||||
{ ngx_string("http3"), NULL, ngx_http_variable_http3,
|
||||
0, 0, 0 },
|
||||
@ -195,26 +85,6 @@ static ngx_http_variable_t ngx_http_v3_vars[] = {
|
||||
};
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_variable_quic(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
{
|
||||
if (r->connection->qs) {
|
||||
|
||||
v->len = 4;
|
||||
v->valid = 1;
|
||||
v->no_cacheable = 1;
|
||||
v->not_found = 0;
|
||||
v->data = (u_char *) "quic";
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
v->not_found = 1;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_variable_http3(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
@ -264,31 +134,6 @@ ngx_http_v3_create_srv_conf(ngx_conf_t *cf)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* set by ngx_pcalloc():
|
||||
* v3cf->quic.original_dcid = { 0, NULL };
|
||||
* v3cf->quic.initial_scid = { 0, NULL };
|
||||
* v3cf->quic.retry_scid = { 0, NULL };
|
||||
* v3cf->quic.stateless_reset_token = { 0 }
|
||||
* conf->quic.preferred_address = NULL
|
||||
*/
|
||||
|
||||
v3cf->quic.max_idle_timeout = NGX_CONF_UNSET_MSEC;
|
||||
v3cf->quic.max_ack_delay = NGX_CONF_UNSET_MSEC;
|
||||
|
||||
v3cf->quic.max_udp_payload_size = NGX_CONF_UNSET_SIZE;
|
||||
v3cf->quic.initial_max_data = NGX_CONF_UNSET_SIZE;
|
||||
v3cf->quic.initial_max_stream_data_bidi_local = NGX_CONF_UNSET_SIZE;
|
||||
v3cf->quic.initial_max_stream_data_bidi_remote = NGX_CONF_UNSET_SIZE;
|
||||
v3cf->quic.initial_max_stream_data_uni = NGX_CONF_UNSET_SIZE;
|
||||
v3cf->quic.initial_max_streams_bidi = NGX_CONF_UNSET_UINT;
|
||||
v3cf->quic.initial_max_streams_uni = NGX_CONF_UNSET_UINT;
|
||||
v3cf->quic.ack_delay_exponent = NGX_CONF_UNSET_UINT;
|
||||
v3cf->quic.disable_active_migration = NGX_CONF_UNSET_UINT;
|
||||
v3cf->quic.active_connection_id_limit = NGX_CONF_UNSET_UINT;
|
||||
|
||||
v3cf->quic.retry = NGX_CONF_UNSET;
|
||||
|
||||
v3cf->max_field_size = NGX_CONF_UNSET_SIZE;
|
||||
v3cf->max_table_capacity = NGX_CONF_UNSET_SIZE;
|
||||
v3cf->max_blocked_streams = NGX_CONF_UNSET_UINT;
|
||||
@ -303,57 +148,6 @@ ngx_http_v3_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
ngx_http_v3_srv_conf_t *prev = parent;
|
||||
ngx_http_v3_srv_conf_t *conf = child;
|
||||
|
||||
ngx_conf_merge_msec_value(conf->quic.max_idle_timeout,
|
||||
prev->quic.max_idle_timeout, 60000);
|
||||
|
||||
ngx_conf_merge_msec_value(conf->quic.max_ack_delay,
|
||||
prev->quic.max_ack_delay,
|
||||
NGX_QUIC_DEFAULT_MAX_ACK_DELAY);
|
||||
|
||||
ngx_conf_merge_size_value(conf->quic.max_udp_payload_size,
|
||||
prev->quic.max_udp_payload_size,
|
||||
NGX_QUIC_MAX_UDP_PAYLOAD_SIZE);
|
||||
|
||||
ngx_conf_merge_size_value(conf->quic.initial_max_data,
|
||||
prev->quic.initial_max_data,
|
||||
16 * NGX_QUIC_STREAM_BUFSIZE);
|
||||
|
||||
ngx_conf_merge_size_value(conf->quic.initial_max_stream_data_bidi_local,
|
||||
prev->quic.initial_max_stream_data_bidi_local,
|
||||
NGX_QUIC_STREAM_BUFSIZE);
|
||||
|
||||
ngx_conf_merge_size_value(conf->quic.initial_max_stream_data_bidi_remote,
|
||||
prev->quic.initial_max_stream_data_bidi_remote,
|
||||
NGX_QUIC_STREAM_BUFSIZE);
|
||||
|
||||
ngx_conf_merge_size_value(conf->quic.initial_max_stream_data_uni,
|
||||
prev->quic.initial_max_stream_data_uni,
|
||||
NGX_QUIC_STREAM_BUFSIZE);
|
||||
|
||||
ngx_conf_merge_uint_value(conf->quic.initial_max_streams_bidi,
|
||||
prev->quic.initial_max_streams_bidi, 16);
|
||||
|
||||
ngx_conf_merge_uint_value(conf->quic.initial_max_streams_uni,
|
||||
prev->quic.initial_max_streams_uni, 16);
|
||||
|
||||
ngx_conf_merge_uint_value(conf->quic.ack_delay_exponent,
|
||||
prev->quic.ack_delay_exponent,
|
||||
NGX_QUIC_DEFAULT_ACK_DELAY_EXPONENT);
|
||||
|
||||
ngx_conf_merge_uint_value(conf->quic.disable_active_migration,
|
||||
prev->quic.disable_active_migration, 1);
|
||||
|
||||
ngx_conf_merge_uint_value(conf->quic.active_connection_id_limit,
|
||||
prev->quic.active_connection_id_limit, 2);
|
||||
|
||||
ngx_conf_merge_value(conf->quic.retry, prev->quic.retry, 0);
|
||||
|
||||
if (conf->quic.retry) {
|
||||
if (RAND_bytes(conf->quic.token_key, sizeof(conf->quic.token_key)) <= 0) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
ngx_conf_merge_size_value(conf->max_field_size,
|
||||
prev->max_field_size,
|
||||
NGX_HTTP_V3_DEFAULT_MAX_FIELD_SIZE);
|
||||
@ -368,40 +162,3 @@ ngx_http_v3_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_v3_max_ack_delay(ngx_conf_t *cf, void *post, void *data)
|
||||
{
|
||||
ngx_msec_t *sp = data;
|
||||
|
||||
if (*sp > 16384) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"\"quic_max_ack_delay\" must be less than 16384");
|
||||
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_v3_max_udp_payload_size(ngx_conf_t *cf, void *post, void *data)
|
||||
{
|
||||
size_t *sp = data;
|
||||
|
||||
if (*sp < NGX_QUIC_MIN_INITIAL_SIZE
|
||||
|| *sp > NGX_QUIC_MAX_UDP_PAYLOAD_SIZE)
|
||||
{
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"\"quic_max_udp_payload_size\" must be between "
|
||||
"%d and %d",
|
||||
NGX_QUIC_MIN_INITIAL_SIZE,
|
||||
NGX_QUIC_MAX_UDP_PAYLOAD_SIZE);
|
||||
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
@ -27,22 +27,55 @@ static void ngx_http_v3_uni_read_handler(ngx_event_t *rev);
|
||||
static void ngx_http_v3_dummy_write_handler(ngx_event_t *wev);
|
||||
static ngx_connection_t *ngx_http_v3_get_uni_stream(ngx_connection_t *c,
|
||||
ngx_uint_t type);
|
||||
static ngx_int_t ngx_http_v3_send_settings(ngx_connection_t *c);
|
||||
|
||||
|
||||
void
|
||||
ngx_http_v3_handle_client_uni_stream(ngx_connection_t *c)
|
||||
ngx_int_t
|
||||
ngx_http_v3_init_connection(ngx_connection_t *c)
|
||||
{
|
||||
ngx_http_connection_t *hc;
|
||||
ngx_http_v3_uni_stream_t *us;
|
||||
ngx_http_v3_connection_t *h3c;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||
"http3 new uni stream id:0x%uxL", c->qs->id);
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 init connection");
|
||||
|
||||
hc = c->data;
|
||||
|
||||
if (c->qs == NULL) {
|
||||
h3c = ngx_pcalloc(c->pool, sizeof(ngx_http_v3_connection_t));
|
||||
if (h3c == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
h3c->hc = *hc;
|
||||
|
||||
ngx_queue_init(&h3c->blocked);
|
||||
|
||||
c->data = h3c;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
h3c = c->qs->parent->data;
|
||||
|
||||
if (!h3c->settings_sent) {
|
||||
h3c->settings_sent = 1;
|
||||
|
||||
if (ngx_http_v3_send_settings(c) != NGX_OK) {
|
||||
ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_INTERNAL_ERROR,
|
||||
"could not send settings");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if ((c->qs->id & NGX_QUIC_STREAM_UNIDIRECTIONAL) == 0) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
us = ngx_pcalloc(c->pool, sizeof(ngx_http_v3_uni_stream_t));
|
||||
if (us == NULL) {
|
||||
ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_INTERNAL_ERROR,
|
||||
NULL);
|
||||
ngx_http_v3_close_uni_stream(c);
|
||||
return;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
us->index = -1;
|
||||
@ -53,6 +86,8 @@ ngx_http_v3_handle_client_uni_stream(ngx_connection_t *c)
|
||||
c->write->handler = ngx_http_v3_dummy_write_handler;
|
||||
|
||||
ngx_http_v3_read_uni_stream_type(c->read);
|
||||
|
||||
return NGX_DONE;
|
||||
}
|
||||
|
||||
|
||||
@ -366,7 +401,7 @@ failed:
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
static ngx_int_t
|
||||
ngx_http_v3_send_settings(ngx_connection_t *c)
|
||||
{
|
||||
u_char *p, buf[NGX_HTTP_V3_VARLEN_INT_LEN * 6];
|
||||
|
Loading…
Reference in New Issue
Block a user