Mercurial > hg > nginx-quic
comparison src/http/modules/ngx_http_quic_module.c @ 7999:0d2b2664b41c quic
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
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Tue, 21 Jul 2020 23:09:22 +0300 |
parents | |
children | 893b3313f53c |
comparison
equal
deleted
inserted
replaced
7998:f537f99b86ee | 7999:0d2b2664b41c |
---|---|
1 | |
2 /* | |
3 * Copyright (C) Nginx, Inc. | |
4 * Copyright (C) Roman Arutyunyan | |
5 */ | |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_http.h> | |
11 | |
12 | |
13 static ngx_int_t ngx_http_variable_quic(ngx_http_request_t *r, | |
14 ngx_http_variable_value_t *v, uintptr_t data); | |
15 static ngx_int_t ngx_http_quic_add_variables(ngx_conf_t *cf); | |
16 static void *ngx_http_quic_create_srv_conf(ngx_conf_t *cf); | |
17 static char *ngx_http_quic_merge_srv_conf(ngx_conf_t *cf, void *parent, | |
18 void *child); | |
19 static char *ngx_http_quic_max_ack_delay(ngx_conf_t *cf, void *post, | |
20 void *data); | |
21 static char *ngx_http_quic_max_udp_payload_size(ngx_conf_t *cf, void *post, | |
22 void *data); | |
23 | |
24 | |
25 static ngx_conf_post_t ngx_http_quic_max_ack_delay_post = | |
26 { ngx_http_quic_max_ack_delay }; | |
27 static ngx_conf_post_t ngx_http_quic_max_udp_payload_size_post = | |
28 { ngx_http_quic_max_udp_payload_size }; | |
29 static ngx_conf_num_bounds_t ngx_http_quic_ack_delay_exponent_bounds = | |
30 { ngx_conf_check_num_bounds, 0, 20 }; | |
31 static ngx_conf_num_bounds_t ngx_http_quic_active_connection_id_limit_bounds = | |
32 { ngx_conf_check_num_bounds, 2, -1 }; | |
33 | |
34 | |
35 static ngx_command_t ngx_http_quic_commands[] = { | |
36 | |
37 { ngx_string("quic_max_idle_timeout"), | |
38 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
39 ngx_conf_set_msec_slot, | |
40 NGX_HTTP_SRV_CONF_OFFSET, | |
41 offsetof(ngx_quic_conf_t, tp.max_idle_timeout), | |
42 NULL }, | |
43 | |
44 { ngx_string("quic_max_ack_delay"), | |
45 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
46 ngx_conf_set_msec_slot, | |
47 NGX_HTTP_SRV_CONF_OFFSET, | |
48 offsetof(ngx_quic_conf_t, tp.max_ack_delay), | |
49 &ngx_http_quic_max_ack_delay_post }, | |
50 | |
51 { ngx_string("quic_max_udp_payload_size"), | |
52 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
53 ngx_conf_set_size_slot, | |
54 NGX_HTTP_SRV_CONF_OFFSET, | |
55 offsetof(ngx_quic_conf_t, tp.max_udp_payload_size), | |
56 &ngx_http_quic_max_udp_payload_size_post }, | |
57 | |
58 { ngx_string("quic_initial_max_data"), | |
59 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
60 ngx_conf_set_size_slot, | |
61 NGX_HTTP_SRV_CONF_OFFSET, | |
62 offsetof(ngx_quic_conf_t, tp.initial_max_data), | |
63 NULL }, | |
64 | |
65 { ngx_string("quic_initial_max_stream_data_bidi_local"), | |
66 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
67 ngx_conf_set_size_slot, | |
68 NGX_HTTP_SRV_CONF_OFFSET, | |
69 offsetof(ngx_quic_conf_t, tp.initial_max_stream_data_bidi_local), | |
70 NULL }, | |
71 | |
72 { ngx_string("quic_initial_max_stream_data_bidi_remote"), | |
73 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
74 ngx_conf_set_size_slot, | |
75 NGX_HTTP_SRV_CONF_OFFSET, | |
76 offsetof(ngx_quic_conf_t, tp.initial_max_stream_data_bidi_remote), | |
77 NULL }, | |
78 | |
79 { ngx_string("quic_initial_max_stream_data_uni"), | |
80 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
81 ngx_conf_set_size_slot, | |
82 NGX_HTTP_SRV_CONF_OFFSET, | |
83 offsetof(ngx_quic_conf_t, tp.initial_max_stream_data_uni), | |
84 NULL }, | |
85 | |
86 { ngx_string("quic_initial_max_streams_bidi"), | |
87 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
88 ngx_conf_set_num_slot, | |
89 NGX_HTTP_SRV_CONF_OFFSET, | |
90 offsetof(ngx_quic_conf_t, tp.initial_max_streams_bidi), | |
91 NULL }, | |
92 | |
93 { ngx_string("quic_initial_max_streams_uni"), | |
94 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
95 ngx_conf_set_num_slot, | |
96 NGX_HTTP_SRV_CONF_OFFSET, | |
97 offsetof(ngx_quic_conf_t, tp.initial_max_streams_uni), | |
98 NULL }, | |
99 | |
100 { ngx_string("quic_ack_delay_exponent"), | |
101 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
102 ngx_conf_set_num_slot, | |
103 NGX_HTTP_SRV_CONF_OFFSET, | |
104 offsetof(ngx_quic_conf_t, tp.ack_delay_exponent), | |
105 &ngx_http_quic_ack_delay_exponent_bounds }, | |
106 | |
107 { ngx_string("quic_active_migration"), | |
108 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
109 ngx_conf_set_num_slot, | |
110 NGX_HTTP_SRV_CONF_OFFSET, | |
111 offsetof(ngx_quic_conf_t, tp.disable_active_migration), | |
112 NULL }, | |
113 | |
114 { ngx_string("quic_active_connection_id_limit"), | |
115 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, | |
116 ngx_conf_set_num_slot, | |
117 NGX_HTTP_SRV_CONF_OFFSET, | |
118 offsetof(ngx_quic_conf_t, tp.active_connection_id_limit), | |
119 &ngx_http_quic_active_connection_id_limit_bounds }, | |
120 | |
121 { ngx_string("quic_retry"), | |
122 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG, | |
123 ngx_conf_set_flag_slot, | |
124 NGX_HTTP_SRV_CONF_OFFSET, | |
125 offsetof(ngx_quic_conf_t, retry), | |
126 NULL }, | |
127 | |
128 ngx_null_command | |
129 }; | |
130 | |
131 | |
132 static ngx_http_module_t ngx_http_quic_module_ctx = { | |
133 ngx_http_quic_add_variables, /* preconfiguration */ | |
134 NULL, /* postconfiguration */ | |
135 | |
136 NULL, /* create main configuration */ | |
137 NULL, /* init main configuration */ | |
138 | |
139 ngx_http_quic_create_srv_conf, /* create server configuration */ | |
140 ngx_http_quic_merge_srv_conf, /* merge server configuration */ | |
141 | |
142 NULL, /* create location configuration */ | |
143 NULL /* merge location configuration */ | |
144 }; | |
145 | |
146 | |
147 ngx_module_t ngx_http_quic_module = { | |
148 NGX_MODULE_V1, | |
149 &ngx_http_quic_module_ctx, /* module context */ | |
150 ngx_http_quic_commands, /* module directives */ | |
151 NGX_HTTP_MODULE, /* module type */ | |
152 NULL, /* init master */ | |
153 NULL, /* init module */ | |
154 NULL, /* init process */ | |
155 NULL, /* init thread */ | |
156 NULL, /* exit thread */ | |
157 NULL, /* exit process */ | |
158 NULL, /* exit master */ | |
159 NGX_MODULE_V1_PADDING | |
160 }; | |
161 | |
162 | |
163 static ngx_http_variable_t ngx_http_quic_vars[] = { | |
164 | |
165 { ngx_string("quic"), NULL, ngx_http_variable_quic, 0, 0, 0 }, | |
166 | |
167 ngx_http_null_variable | |
168 }; | |
169 | |
170 | |
171 static ngx_int_t | |
172 ngx_http_variable_quic(ngx_http_request_t *r, | |
173 ngx_http_variable_value_t *v, uintptr_t data) | |
174 { | |
175 if (r->connection->qs) { | |
176 | |
177 v->len = 4; | |
178 v->valid = 1; | |
179 v->no_cacheable = 1; | |
180 v->not_found = 0; | |
181 v->data = (u_char *) "quic"; | |
182 return NGX_OK; | |
183 } | |
184 | |
185 v->not_found = 1; | |
186 | |
187 return NGX_OK; | |
188 } | |
189 | |
190 | |
191 static ngx_int_t | |
192 ngx_http_quic_add_variables(ngx_conf_t *cf) | |
193 { | |
194 ngx_http_variable_t *var, *v; | |
195 | |
196 for (v = ngx_http_quic_vars; v->name.len; v++) { | |
197 var = ngx_http_add_variable(cf, &v->name, v->flags); | |
198 if (var == NULL) { | |
199 return NGX_ERROR; | |
200 } | |
201 | |
202 var->get_handler = v->get_handler; | |
203 var->data = v->data; | |
204 } | |
205 | |
206 return NGX_OK; | |
207 } | |
208 | |
209 | |
210 static void * | |
211 ngx_http_quic_create_srv_conf(ngx_conf_t *cf) | |
212 { | |
213 ngx_quic_conf_t *conf; | |
214 | |
215 conf = ngx_pcalloc(cf->pool, sizeof(ngx_quic_conf_t)); | |
216 if (conf == NULL) { | |
217 return NULL; | |
218 } | |
219 | |
220 /* | |
221 * set by ngx_pcalloc(): | |
222 * | |
223 * conf->tp.original_dcid = { 0, NULL }; | |
224 * conf->tp.initial_scid = { 0, NULL }; | |
225 * conf->tp.retry_scid = { 0, NULL }; | |
226 * conf->tp.stateless_reset_token = { 0 } | |
227 * conf->tp.preferred_address = NULL | |
228 */ | |
229 | |
230 conf->tp.max_idle_timeout = NGX_CONF_UNSET_MSEC; | |
231 conf->tp.max_ack_delay = NGX_CONF_UNSET_MSEC; | |
232 conf->tp.max_udp_payload_size = NGX_CONF_UNSET_SIZE; | |
233 conf->tp.initial_max_data = NGX_CONF_UNSET_SIZE; | |
234 conf->tp.initial_max_stream_data_bidi_local = NGX_CONF_UNSET_SIZE; | |
235 conf->tp.initial_max_stream_data_bidi_remote = NGX_CONF_UNSET_SIZE; | |
236 conf->tp.initial_max_stream_data_uni = NGX_CONF_UNSET_SIZE; | |
237 conf->tp.initial_max_streams_bidi = NGX_CONF_UNSET_UINT; | |
238 conf->tp.initial_max_streams_uni = NGX_CONF_UNSET_UINT; | |
239 conf->tp.ack_delay_exponent = NGX_CONF_UNSET_UINT; | |
240 conf->tp.disable_active_migration = NGX_CONF_UNSET_UINT; | |
241 conf->tp.active_connection_id_limit = NGX_CONF_UNSET_UINT; | |
242 | |
243 conf->retry = NGX_CONF_UNSET; | |
244 | |
245 return conf; | |
246 } | |
247 | |
248 | |
249 static char * | |
250 ngx_http_quic_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) | |
251 { | |
252 ngx_quic_conf_t *prev = parent; | |
253 ngx_quic_conf_t *conf = child; | |
254 | |
255 ngx_conf_merge_msec_value(conf->tp.max_idle_timeout, | |
256 prev->tp.max_idle_timeout, 60000); | |
257 | |
258 ngx_conf_merge_msec_value(conf->tp.max_ack_delay, | |
259 prev->tp.max_ack_delay, | |
260 NGX_QUIC_DEFAULT_MAX_ACK_DELAY); | |
261 | |
262 ngx_conf_merge_size_value(conf->tp.max_udp_payload_size, | |
263 prev->tp.max_udp_payload_size, | |
264 NGX_QUIC_MAX_UDP_PAYLOAD_SIZE); | |
265 | |
266 ngx_conf_merge_size_value(conf->tp.initial_max_data, | |
267 prev->tp.initial_max_data, | |
268 16 * NGX_QUIC_STREAM_BUFSIZE); | |
269 | |
270 ngx_conf_merge_size_value(conf->tp.initial_max_stream_data_bidi_local, | |
271 prev->tp.initial_max_stream_data_bidi_local, | |
272 NGX_QUIC_STREAM_BUFSIZE); | |
273 | |
274 ngx_conf_merge_size_value(conf->tp.initial_max_stream_data_bidi_remote, | |
275 prev->tp.initial_max_stream_data_bidi_remote, | |
276 NGX_QUIC_STREAM_BUFSIZE); | |
277 | |
278 ngx_conf_merge_size_value(conf->tp.initial_max_stream_data_uni, | |
279 prev->tp.initial_max_stream_data_uni, | |
280 NGX_QUIC_STREAM_BUFSIZE); | |
281 | |
282 ngx_conf_merge_uint_value(conf->tp.initial_max_streams_bidi, | |
283 prev->tp.initial_max_streams_bidi, 16); | |
284 | |
285 ngx_conf_merge_uint_value(conf->tp.initial_max_streams_uni, | |
286 prev->tp.initial_max_streams_uni, 16); | |
287 | |
288 ngx_conf_merge_uint_value(conf->tp.ack_delay_exponent, | |
289 prev->tp.ack_delay_exponent, | |
290 NGX_QUIC_DEFAULT_ACK_DELAY_EXPONENT); | |
291 | |
292 ngx_conf_merge_uint_value(conf->tp.disable_active_migration, | |
293 prev->tp.disable_active_migration, 1); | |
294 | |
295 ngx_conf_merge_uint_value(conf->tp.active_connection_id_limit, | |
296 prev->tp.active_connection_id_limit, 2); | |
297 | |
298 ngx_conf_merge_value(conf->retry, prev->retry, 0); | |
299 | |
300 if (conf->retry) { | |
301 if (RAND_bytes(conf->token_key, sizeof(conf->token_key)) <= 0) { | |
302 return NGX_CONF_ERROR; | |
303 } | |
304 } | |
305 | |
306 return NGX_CONF_OK; | |
307 } | |
308 | |
309 | |
310 static char * | |
311 ngx_http_quic_max_ack_delay(ngx_conf_t *cf, void *post, void *data) | |
312 { | |
313 ngx_msec_t *sp = data; | |
314 | |
315 if (*sp > 16384) { | |
316 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
317 "\"quic_max_ack_delay\" must be less than 16384"); | |
318 | |
319 return NGX_CONF_ERROR; | |
320 } | |
321 | |
322 return NGX_CONF_OK; | |
323 } | |
324 | |
325 | |
326 static char * | |
327 ngx_http_quic_max_udp_payload_size(ngx_conf_t *cf, void *post, void *data) | |
328 { | |
329 size_t *sp = data; | |
330 | |
331 if (*sp < NGX_QUIC_MIN_INITIAL_SIZE | |
332 || *sp > NGX_QUIC_MAX_UDP_PAYLOAD_SIZE) | |
333 { | |
334 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
335 "\"quic_max_udp_payload_size\" must be between " | |
336 "%d and %d", | |
337 NGX_QUIC_MIN_INITIAL_SIZE, | |
338 NGX_QUIC_MAX_UDP_PAYLOAD_SIZE); | |
339 | |
340 return NGX_CONF_ERROR; | |
341 } | |
342 | |
343 return NGX_CONF_OK; | |
344 } |